import pyxel
import random
import math
# Modificateur de difficulté et paramètres du donjon
class Lvl_modif:
    def __init__(self, level):
        self.lvl_actu = level
        self.salle = self.lvl_actu
        #vitesse ennemis
        self.vitesse_slime = self.lvl_actu
        self.vitesse_boss = 1.5 * self.lvl_actu
        self.nb_ennemis = 3 - (self.lvl_actu // 10)
        #pv ennemis
        self.pv_ennemi_slime = 0.75 * self.lvl_actu
        self.pv_ennemi_tireur = 1 + 0.25* self.lvl_actu
        self.pv_boss = 5 + 1.75 * self.lvl_actu
        #cooldown
        self.cooldown_slime = self.lvl_actu // 10
        self.cooldown_tireur = 2 * (self.lvl_actu // 10)
        self.cooldown_tir_boss = 5 * (self.lvl_actu // 10)
        self.cooldown_mouv_boss = self.lvl_actu // 10
        self.cooldown_invocation_boss = self.lvl_actu
        
        
L_salle = 256
H_salle = 192
# Taille de la grille pour la génération
L_grille = 16
H_grille = 16
def creer_grille(L_grille, H_grille):
    grille = [[None for i in range(L_grille)] for j in range(H_grille)]
    return grille
# Classe Salle gere les aspects et elements present dans la salle 
class Salle:
    def __init__(self, x, y):
        self.x, self.y = x, y
        self.portes = {
            "Nord": False,
            "Sud": False,
            "Ouest": False,
            "Est": False}
        self.portes_type = {
            "Nord": 1,
            "Sud": 1,
            "Ouest": 1,
            "Est": 1}
        self.portes_visitees = {
            "Nord": False,
            "Sud": False,
            "Ouest": False,
            "Est": False}
        self.depart_ennemi = {
            "1":{"active": False,"x": 64,"y": 48} ,
            "2":{"active": False,"x": 64,"y": 144} ,
            "3":{"active": False,"x": 112,"y": 96} ,
            "4":{"active": False,"x": 192,"y": 48} ,
            "5":{"active": False,"x": 192,"y": 144} ,
            "6":{"active": False,"x": 144,"y": 96} }
        self.ennemis = []
        self.caisses = []
        self.rubis = None
        self.type = 1
        #pour la salle de clee
        self.cle_disponible = False
        #pour la salle de boss
        self.porte_de_sortie = False
        #pour la salle de fin
        self.explosion = False
        self.temps_entree = 0
        #pour la salle d'achat
        self.buff = []
        self.rubis = []
        
    def salle_classique(self):
        pyxel.blt(0, 0, 0, 0, 0, 16, 16)#coin haut g
        
        for i in range((L_salle-32)//32):#mur haut
            pyxel.blt(16+(i*32), 0, 0, 16, 0, 32, 16)
        
        pyxel.blt(L_salle-16, 0, 0, 48, 0, 16, 16)#coin haut droit
        
        for j in range((H_salle-32)//32):#mur gauche
            pyxel.blt(0, 16+(j*32), 0, 0, 16, 16, 32)
        
        pyxel.blt(0, H_salle-16, 0, 0, 48, 16, 16)#coin bas gauche
        
        for k in range((L_salle-32)//32):#mur bas
            pyxel.blt(16+(k*32), H_salle-16, 0, 16, 48, 32, 16)
        
        pyxel.blt(L_salle-16, H_salle-16, 0, 48, 48, 16, 16)#coin bas droite
        
        for l in range((H_salle-32)//32):#mur droite
            pyxel.blt(L_salle-16, 16+(l*32), 0, 48, 16, 16, 32)
            
        for n in range((L_salle-32)//32):
            for m in range((H_salle-32)//32):#terrain
                pyxel.blt(16+(n*32), 16+(m*32), 0, 16, 16, 32, 32)

        if self.portes["Nord"]:
            if self.portes_type["Nord"] == 3:
                pyxel.blt(L_salle//2-8, 0, 0, 0, 80, 16, 16)
            elif self.portes_type["Nord"] == 0:
                pyxel.blt(L_salle//2-8, 0, 0, 0, 96, 16, 16)
            else:
                pyxel.blt(L_salle//2-8, 0, 0, 0, 64, 16, 16)
            if self.ennemis != []:
                pyxel.blt(L_salle//2-8, 0, 0, 64, 96, 16, 16, 1)
            if self.portes_visitees["Nord"]:
                pyxel.blt(L_salle//2 + 8, 0, 0, 6, 144, 4, 16)
            else:
                pyxel.blt(L_salle//2 + 8, 0, 0, 6, 112, 6, 16)
        
        if self.portes["Sud"]:
            if self.portes_type["Sud"] == 3:
                pyxel.blt(L_salle//2-8, H_salle-16, 0, 32, 80, 16, 16)
            elif self.portes_type["Sud"] == 0:
                pyxel.blt(L_salle//2-8, H_salle-16, 0, 32, 96, 16, 16)
            else:
                pyxel.blt(L_salle//2-8, H_salle-16, 0, 32, 64, 16, 16)
            if self.ennemis != []:
                pyxel.blt(L_salle//2-8, H_salle-16, 0, 96, 96, 16, 16, 1)
            if self.portes_visitees["Sud"]:
                pyxel.blt(L_salle//2 + 8, H_salle-16, 0, 38, 144, 4, 16)
            else:
                pyxel.blt(L_salle//2 + 8, H_salle-16, 0, 38, 112, 4, 16)
        
        if self.portes["Ouest"]:
            if self.portes_type["Ouest"] == 3:
                pyxel.blt(0, H_salle//2-8, 0, 16, 80, 16, 16)
            elif self.portes_type["Ouest"] == 0:
                pyxel.blt(0, H_salle//2-8, 0, 16, 96, 16, 16)
            else:
                pyxel.blt(0, H_salle//2-8, 0, 16, 64, 16, 16)
            if self.ennemis != []:
                pyxel.blt(0, H_salle//2-8, 0, 80, 96, 16, 16, 1)
            if self.portes_visitees["Ouest"]:
                pyxel.blt(0, H_salle//2-12, 0, 16, 150, 16, 4)
            else:
                pyxel.blt(0, H_salle//2-12, 0, 16, 118, 16, 4)
        
        if self.portes["Est"]:
            if self.portes_type["Est"] == 3:
                pyxel.blt(L_salle-16, H_salle//2-8, 0, 48, 80, 16, 16)
            elif self.portes_type["Est"] == 0:
                pyxel.blt(L_salle-16, H_salle//2-8, 0, 48, 96, 16, 16)
            else:
                pyxel.blt(L_salle-16, H_salle//2-8, 0, 48, 64, 16, 16)
            if self.ennemis != []:
                pyxel.blt(L_salle-16, H_salle//2-8, 0, 112, 96, 16, 16, 1)
            if self.portes_visitees["Est"]:
                pyxel.blt(L_salle-16, H_salle//2-12, 0, 48, 150, 16, 4)
            else:
                pyxel.blt(L_salle-16, H_salle//2-12, 0, 48, 118, 16, 4)
            
    def salle_depart(self):
        #self.type = 0  # Type 0 = salle de départ
        
        pyxel.blt(0, 0, 0, 64, 0, 16, 16)#coin haut g
        
        for i in range((L_salle-32)//32):#mur haut
            pyxel.blt(16+(i*32), 0, 0, 80, 0, 32, 16)
        
        pyxel.blt(L_salle-16, 0, 0, 112, 0, 16, 16)#coin haut droit
        
        for j in range((H_salle-32)//32):#mur gauche
            pyxel.blt(0, 16+(j*32), 0, 64, 16, 16, 32)
        
        pyxel.blt(0, H_salle-16, 0, 64, 48, 16, 16)#coin bas gauche
        
        for k in range((L_salle-32)//32):#mur bas
            pyxel.blt(16+(k*32), H_salle-16, 0, 80, 48, 32, 16)
        
        pyxel.blt(L_salle-16, H_salle-16, 0, 112, 48, 16, 16)#coin bas droite
        
        for l in range((H_salle-32)//32):#mur droite
            pyxel.blt(L_salle-16, 16+(l*32), 0, 112, 16, 16, 32)
            
        for n in range((L_salle-32)//32):
            for m in range((H_salle-32)//32):#terrain
                pyxel.blt(16+(n*32), 16+(m*32), 0, 80, 16, 32, 32)
        
        pyxel.blt((L_salle-32)//2-64, (H_salle-32)//2+16, 0, 80, 128, 32, 32)
        
        pyxel.blt((L_salle-32)//2+64, (H_salle-32)//2+32, 0, 112, 144, 32, 16)

        pyxel.blt((L_salle-32)//2 , (H_salle-64)//2+32, 0, 112, 160, 32, 16, 1)
        # Dessiner les portes si elles existent
        if self.portes["Nord"]:
            if self.portes_type["Nord"] == 3:
                pyxel.blt(L_salle//2-8, 0, 0, 64, 80, 16, 16)
            else:
                pyxel.blt(L_salle//2-8, 0, 0, 64, 64, 16, 16)
            if self.portes_visitees["Nord"]:
                pyxel.blt(L_salle//2 + 8, 0, 0, 6, 176, 4, 16)
            else:
                pyxel.blt(L_salle//2 + 8, 0, 0, 6, 160, 6, 16)
        
        if self.portes["Sud"]:
            if self.portes_type["Sud"] == 3:
                pyxel.blt(L_salle//2-8, H_salle-16, 0, 96, 80, 16, 16)
            else:
                pyxel.blt(L_salle//2-8, H_salle-16, 0, 96, 64, 16, 16)
            if self.portes_visitees["Sud"]:
                pyxel.blt(L_salle//2 + 8, H_salle-16, 0, 38, 176, 4, 16)
            else:
                pyxel.blt(L_salle//2 + 8, H_salle-16, 0, 38, 160, 4, 16)
        
        if self.portes["Ouest"]:
            if self.portes_type["Ouest"] == 3:
                pyxel.blt(0, H_salle//2-8, 0, 80, 80, 16, 16)
            else:
                pyxel.blt(0, H_salle//2-8, 0, 80, 64, 16, 16)
            if self.portes_visitees["Ouest"]:
                pyxel.blt(0, H_salle//2-12, 0, 16, 182, 16, 4)
            else:
                pyxel.blt(0, H_salle//2-12, 0, 16, 166, 16, 4)
        
        if self.portes["Est"]:
            if self.portes_type["Est"] == 3:
                pyxel.blt(L_salle-16, H_salle//2-8, 0, 112, 80, 16, 16)
            else:
                pyxel.blt(L_salle-16, H_salle//2-8, 0, 112, 64, 16, 16)
            if self.portes_visitees["Est"]:
                pyxel.blt(L_salle-16, H_salle//2-12, 0, 48, 182, 16, 4)
            else:
                pyxel.blt(L_salle-16, H_salle//2-12, 0, 48, 166, 16, 4)

    def salle_boss(self):
        #self.type = 3
        
        pyxel.blt(0, 0, 0, 128, 0, 16, 16)#coin haut g
        
        for i in range((L_salle-32)//32):#mur haut
            pyxel.blt(16+(i*32), 0, 0, 144, 0, 32, 16)
        
        pyxel.blt(L_salle-16, 0, 0, 176, 0, 16, 16)#coin haut droit
        
        for j in range((H_salle-32)//32):#mur gauche
            pyxel.blt(0, 16+(j*32), 0, 128, 16, 16, 32)
        
        pyxel.blt(0, H_salle-16, 0, 128, 48, 16, 16)#coin bas gauche
        
        for k in range((L_salle-32)//32):#mur bas
            pyxel.blt(16+(k*32), H_salle-16, 0, 144, 48, 32, 16)
        
        pyxel.blt(L_salle-16, H_salle-16, 0, 176, 48, 16, 16)#coin bas droite
        
        for l in range((H_salle-32)//32):#mur droite
            pyxel.blt(L_salle-16, 16+(l*32), 0, 176, 16, 16, 32)
            
        
        for n in range((L_salle-32)//32):
            for m in range((H_salle-32)//32):#terrain
                pyxel.blt(16+(n*32), 16+(m*32), 0, 144, 16, 32, 32)
        # Dessine le fond de la salle
        # Dessiner les portes si elles existent
        if self.portes["Nord"]:
            if self.portes_type["Nord"] == 0:
                pyxel.blt(L_salle//2-8, 0, 0, 128, 80, 16, 16)
            else:
                pyxel.blt(L_salle//2-8, 0, 0, 128, 64, 16, 16)
            if self.ennemis != []:
                pyxel.blt(L_salle//2-8, 0, 0, 128, 96, 16, 16, 1)
                
        if self.portes["Sud"]:
            if self.portes_type["Sud"] == 0:
                pyxel.blt(L_salle//2-8, H_salle-16, 0, 160, 80, 16, 16)
            else:
                pyxel.blt(L_salle//2-8, H_salle-16, 0, 160, 64, 16, 16)
            if self.ennemis != []:
                pyxel.blt(L_salle//2-8, H_salle-16, 0, 160, 96, 16, 16, 1)
                
        if self.portes["Ouest"]:
            if self.portes_type["Ouest"] == 0:
                pyxel.blt(0, H_salle//2-8, 0, 144, 80, 16, 16)
            else:
                pyxel.blt(0, H_salle//2-8, 0, 144, 64, 16, 16)
            if self.ennemis != []:
                pyxel.blt(0, H_salle//2-8, 0, 144, 96, 16, 16, 1)
                
        if self.portes["Est"]:
            if self.portes_type["Est"] == 0:
                pyxel.blt(L_salle-16, H_salle//2-8, 0, 176, 80, 16, 16)
            else:
                pyxel.blt(L_salle-16, H_salle//2-8, 0, 176, 64, 16, 16)
            if self.ennemis != []:
                pyxel.blt(L_salle-16, H_salle//2-8, 0, 176, 96, 16, 16, 1)

        for caisse in self.caisses:
            caisse.rubis = False
                
        if self.porte_de_sortie:
            pyxel.blt(L_salle//2 - 8, H_salle//2 - 8, 0, 32, 128, 16, 16, 1)

    
    def salle_fin(self):
        self.ennemis = []
        self.caisses = []
        self.salle_classique()
        self.accès_fin()

    def salle_achat(self):
        self.ennemis = []
        self.caisses = []
        self.salle_classique()
        pyxel.blt(L_salle//2 - 32, H_salle//2 - 16, 0, 80, 176, 64, 32, 1)
        i = 0
        for buff in self.buff:
            pyxel.blt(L_salle//2 - 24 + i * 30, H_salle//2 - 14, 0, 64, 200, 16, 24, 9)
            if buff:
                pyxel.blt(L_salle//2 - 24 + i * 30, H_salle//2 + 5, 0, 64, 176, 16, 16, 1)
                pyxel.blt(L_salle//2 - 20 + i * 30, H_salle//2 - 8, *buff["sprite"])
                pyxel.text(L_salle//2 - 20 + i * 30, H_salle//2 + 9, str(buff['prix']), pyxel.COLOR_WHITE)
            i += 1

    def accès_fin(self):
        if self.temps_entree == 0:
            self.temps_entree = pyxel.frame_count

        if pyxel.frame_count - self.temps_entree < 90:
            if self.portes["Nord"]:
                pyxel.blt(L_salle//2-24, H_salle - 32, 1, 80, 96, 16, 16, 1)
                pyxel.blt(L_salle//2+8, H_salle - 32, 1, 80, 96, 16, 16, 1)
            if self.portes["Sud"]:
                pyxel.blt(L_salle//2-24, 16, 1, 80, 96, 16, 16, 1)
                pyxel.blt(L_salle//2+8, 16, 1, 80, 96, 16, 16, 1)
            if self.portes["Ouest"]:
                pyxel.blt(L_salle - 32, H_salle//2-24, 1, 80, 96, 16, 16, 1)
                pyxel.blt(L_salle - 32, H_salle//2+8, 1, 80, 96, 16, 16, 1)
            if self.portes["Est"]:
                pyxel.blt(16, H_salle//2-24, 1, 80, 96, 16, 16, 1)
                pyxel.blt(16, H_salle//2+8, 1, 80, 96, 16, 16, 1)
        elif pyxel.frame_count - self.temps_entree < 110:
            self.explosion = True
            if self.portes["Nord"]:
                pyxel.blt(L_salle//2-24, H_salle - 16, 1, 80, 112, 32, 32, 1)
                pyxel.blt(L_salle//2+8, H_salle - 16, 1, 80, 112, 32, 32, 1)
            if self.portes["Sud"]:
                pyxel.blt(L_salle//2-24, 0, 1, 80, 112, 32, 32, 1)
                pyxel.blt(L_salle//2+8, 0, 1, 80, 112, 32, 32, 1)
            if self.portes["Ouest"]:
                pyxel.blt(L_salle - 16, H_salle//2-24, 1, 80, 112, 32, 32, 1)
                pyxel.blt(L_salle - 16, H_salle//2+8, 1, 80, 112, 32, 32, 1)
            if self.portes["Est"]:
                pyxel.blt(0, H_salle//2-24, 1, 80, 112, 32, 32, 1)
                pyxel.blt(0, H_salle//2+8, 1, 80, 112, 32, 32, 1)
        else:
            self.explosion = False
            if self.portes["Nord"]:
                pyxel.blt(L_salle//2-16, H_salle - 16, 0, 16, 208, 32, 16)
            if self.portes["Sud"]:
                pyxel.blt(L_salle//2-16, 0, 0, 16, 192, 32, 16)
            if self.portes["Ouest"]:
                pyxel.blt(L_salle - 16, H_salle//2-16, 0, 48, 192, 16, 32)
            if self.portes["Est"]:
                pyxel.blt(0, H_salle//2-16, 0, 0, 192, 16, 32)

    def detecter_collision_fin(self, joueur):
        if self.portes["Nord"] and L_salle // 2 - 16 < joueur.coo_x < L_salle // 2 + 16 and H_salle - 24 < joueur.coo_y < H_salle:
            return True
        if self.portes["Sud"] and L_salle // 2 - 16 < joueur.coo_x < L_salle // 2 + 16 and 0 < joueur.coo_y < 24:
            return True
        if self.portes["Ouest"] and L_salle - 24 < joueur.coo_x < L_salle and H_salle // 2 - 16 < joueur.coo_y < H_salle // 2 + 16:
            return True
        if self.portes["Est"] and 0 < joueur.coo_x < 24 and H_salle // 2 - 16 < joueur.coo_y < H_salle // 2 + 16:
            return True
        return False

    def check_boss_defeat(self):
        if self.type == 3 and not self.ennemis:
            self.porte_de_sortie = True

    def salle_clee(self):
        #self.type =2
        self.salle_classique()
        pyxel.blt(L_salle//2-8, H_salle//2-8, 0, 0, 128, 16, 16)
        if self.cle_disponible:
            pyxel.blt(L_salle//2-4, H_salle//2-6, 0, 16, 136, 8, 8, 1)
        
        
    def Ennemis_draw(self):
        for ennemi in self.ennemis:
            ennemi.dessiner()

    def Caisse_draw(self):
        for caisse in self.caisses:
            caisse.dessiner()
        if self.rubis:
            self.rubis.dessiner()
    
    def Ennemis_update(self, joueur):
        for ennemi in self.ennemis:
            ennemi.update(joueur)
            if ennemi.est_touche_par_joueur(joueur):
                if joueur.direction == "Nord":
                    joueur.coo_y += 16
                    joueur.vie -=1
                if joueur.direction == "Sud":
                    joueur.coo_y -= 16
                    joueur.vie -=1
                if joueur.direction == "Est":
                    joueur.coo_x -= 16
                    joueur.vie -=1
                if joueur.direction == "Ouest":
                    joueur.coo_x += 16
                    joueur.vie -=1
            for projectile in joueur.projectiles:
                if ennemi.est_touche_par_tir(projectile):
                    ennemi.vie -= projectile.degat
                    projectile.actif = False
        
        self.ennemis = [e for e in self.ennemis if e.vie > 0]

    def Caisse_update(self, joueur):
        for caisse in self.caisses:
            for projectile in joueur.projectiles:
                if caisse.est_touche_par_projectile(projectile):
                    caisse.vie -= 1
                    projectile.actif = False
            for ennemi in self.ennemis:
                if not isinstance(ennemi, Creeper):
                    for projectile in ennemi.projectiles:
                        if caisse.est_touche_par_projectile(projectile):
                            caisse.vie -= 1
                            projectile.actif = False

            for ennemi in self.ennemis:
                if caisse.est_touche_par_ennemi(ennemi):
                    if isinstance(ennemi, slime):
                        caisse.vie -= 1
                        if ennemi.direction == "Nord":
                            ennemi.y += ennemi.vitesse
                        if ennemi.direction == "Sud":
                            ennemi.y -= ennemi.vitesse
                        if ennemi.direction == "Est":
                            ennemi.x -= ennemi.vitesse
                        if ennemi.direction == "Ouest":
                            ennemi.x += ennemi.vitesse
                    elif isinstance(ennemi, Tireur): 
                        if ennemi.direction == "Sud":
                            ennemi.y += 8
                        if ennemi.direction == "Nord":
                            ennemi.y -= 8
                        if ennemi.direction == "Ouest":
                            ennemi.x -= 8
                        if ennemi.direction == "Est":
                            ennemi.x += 8
                    else: 
                        if ennemi.direction == "Nord":
                            ennemi.y += ennemi.vitesse
                        if ennemi.direction == "Sud":
                            ennemi.y -= ennemi.vitesse
                        if ennemi.direction == "Est":
                            ennemi.x -= ennemi.vitesse
                        if ennemi.direction == "Ouest":
                            ennemi.x += ennemi.vitesse
            if caisse.est_touche_par_joueur(joueur):
                if joueur.direction == "Nord":
                    joueur.coo_y += joueur.vitesse
                if joueur.direction == "Sud":
                    joueur.coo_y -= joueur.vitesse
                if joueur.direction == "Est":
                    joueur.coo_x -= joueur.vitesse
                if joueur.direction == "Ouest":
                    joueur.coo_x += joueur.vitesse
        
        for caisse in self.caisses:
            if caisse.vie <= 0 and caisse.rubis:
                self.rubis = Rubis(caisse.x, caisse.y, self)

        self.caisses = [c for c in self.caisses if c.vie > 0]

#gere les rubis
class Rubis:
    def __init__(self, x, y, salle):
        self.x = x
        self.y = y
        self.salle = salle
        self.disponible = True

    def dessiner(self):
        if self.disponible:
            pyxel.blt(self.x - 8, self.y - 8, 0, 64, 160, 16, 16, 1)

    def est_touche_par_joueur(self, joueur):
        if self.disponible and self.x - 8 < joueur.coo_x < self.x + 8 and self.y - 8 < joueur.coo_y < self.y + 8:
            self.disponible = False
            return True
        return False
# genere l'entierete du donjon de façon aleatoire et procedurale ainsi que l'ajouts des ennemis ,des caisses et des portes
class Donjon:
    def __init__(self, level_modif):
        self.salles = []
        self.grille = creer_grille(16, 16)
        self.level = level_modif
        self.nb_salle = random.randint(8, 12) + self.level.salle
        self.generer_donjon()
        self.assigner_salle_boss()
        self.assigner_salle_cle()
        self.ajouter_salle_fin()
        self.assigner_porte_de_depart()
        self.assigner_salle_achat()

    def generer_donjon(self):
        """genere le positionnement des salles du donjon en attribuant les portes et types de salles"""
        start_x, start_y = random.randint(0, L_grille-1), random.randint(0, H_grille-1)
        salle_depart = Salle(start_x, start_y)
        salle_depart.salle_depart()
        self.salles.append(salle_depart)
        salle_depart.type = 0
        self.grille[start_y][start_x] = salle_depart

        a_explorer = [salle_depart]
        while len(self.salles) < self.nb_salle and a_explorer:
            salle_actuelle = random.choice(a_explorer)
            
            voisins = self.voisins_vides(salle_actuelle)
            if not voisins:
                a_explorer.remove(salle_actuelle)
                continue

            direction, (nx, ny) = random.choice(voisins)
            nouvelle_salle = Salle(nx, ny)
            
            self.assigner_ennemis_classique(nouvelle_salle)
            self.assigner_caisse(nouvelle_salle)
            self.ajouter_porte(salle_actuelle, nouvelle_salle, direction)
            self.salles.append(nouvelle_salle)
            self.grille[ny][nx] = nouvelle_salle
            a_explorer.append(nouvelle_salle)
        
        #self.verifier_porte_salle_depart()

    def voisins_vides(self, salle):
        directions = {
            "Nord": (0, -1),
            "Sud": (0, 1),
            "Ouest": (-1, 0),
            "Est": (1, 0)}
        voisins_vides = []
        for direction, (dx, dy) in directions.items():
            nx, ny = salle.x + dx, salle.y + dy
            if 0 <= nx and nx < L_grille and 0 <= ny and ny < H_grille:
                if self.grille[ny][nx] is None:
                    voisins_vides.append((direction, (nx, ny)))
        return voisins_vides

    def ajouter_porte(self, s1, s2, direction):
        """Ajoute une porte entre deux salles (salle 1 et salle 2) dans la direction """
        if s2 is not None:
            s1.portes[direction] = True
            if direction == "Nord":
                s2.portes["Sud"] = True
            elif direction == "Sud":
                s2.portes["Nord"] = True
            elif direction == "Ouest":
                s2.portes["Est"] = True
            elif direction == "Est":
                s2.portes["Ouest"] = True
            
    def assigner_salle_boss(self):
        """assigne a une salle avec qu'une porte le role de la salle de boss"""
        salles_une_porte = [s for s in self.salles if sum(s.portes.values()) == 1 and s.type != 0]
        if salles_une_porte != []:
            salle_boss = random.choice(salles_une_porte)
            salle_boss.type = 3
            boss = boss_1(self.level)
            salle_boss.ennemis = [boss]
            boss.salle = salle_boss
            if salle_boss.portes["Nord"]:
                pre_salle_boss = self.grille[salle_boss.y-1][salle_boss.x]
                self.ajouter_porte_speciale(salle_boss, pre_salle_boss, "Nord")
                
            elif salle_boss.portes["Sud"]:
                pre_salle_boss = self.grille[salle_boss.y+1][salle_boss.x]
                self.ajouter_porte_speciale(salle_boss, pre_salle_boss, "Sud")
                
            elif salle_boss.portes["Ouest"]:
                pre_salle_boss = self.grille[salle_boss.y][salle_boss.x-1]
                self.ajouter_porte_speciale(salle_boss, pre_salle_boss, "Ouest")
                
            elif salle_boss.portes["Est"]:
                pre_salle_boss = self.grille[salle_boss.y][salle_boss.x+1]
                self.ajouter_porte_speciale(salle_boss, pre_salle_boss, "Est")
        

    def assigner_salle_cle(self):
        """assigne a une salle autre que la salle de depart et la salle de boss le role de la salle a clee"""
        salles_random = [s for s in self.salles if s is not self.salles[0] and not s.type == 3]
        if salles_random:
            salle_cle = random.choice(salles_random)
            salle_cle.type = 2
            salle_cle.cle_disponible = True
        
    def assigner_porte_de_depart(self):
        """assigne a chaque salle les emplacements des portes"""
        if self.salles[0].portes["Nord"]:
            pre_salle_depart = self.grille[self.salles[0].y-1][self.salles[0].x]
            if pre_salle_depart is not None:
                self.ajouter_porte_speciale(self.salles[0], pre_salle_depart, "Nord")
            
        if self.salles[0].portes["Sud"]:
            pre_salle_depart = self.grille[self.salles[0].y+1][self.salles[0].x]
            if pre_salle_depart is not None:
                self.ajouter_porte_speciale(self.salles[0], pre_salle_depart, "Sud")
            
        if self.salles[0].portes["Ouest"]:
            pre_salle_depart = self.grille[self.salles[0].y][self.salles[0].x-1]
            if pre_salle_depart is not None:
                self.ajouter_porte_speciale(self.salles[0], pre_salle_depart, "Ouest")
            
        if self.salles[0].portes["Est"]:
            pre_salle_depart = self.grille[self.salles[0].y][self.salles[0].x+1]
            if pre_salle_depart is not None:
                self.ajouter_porte_speciale(self.salles[0], pre_salle_depart, "Est")

    def ajouter_salle_fin(self):
        """Assigne à une salle avec une seule porte le rôle de la salle de fin"""
        if self.level.lvl_actu >= 2 and random.random() < 0.2:
            salles_une_porte = [s for s in self.salles if sum(s.portes.values()) == 1 and s.type not in [0, 2, 3]]
            if salles_une_porte:
                salle_fin = random.choice(salles_une_porte)
                salle_fin.type = 4 
            
    def ajouter_porte_speciale(self, s1, s2, direction):
        """Ajoute une porte speciales(pour design boss et depart) entre deux salles (salle 1 et salle 2) dans la direction spécifiée."""
        s1.portes_type[direction] = s2.type
        
        if direction == "Nord":
            s2.portes_type["Sud"] = s1.type
        
        elif direction == "Sud":
            s2.portes_type["Nord"] = s1.type
        
        elif direction == "Ouest":
            s2.portes_type["Est"] = s1.type
        
        elif direction == "Est":
            s2.portes_type["Ouest"] = s1.type
            
    def assigner_ennemis_classique(self, salle):
        salle_actu = salle
        if self.level.lvl_actu <= 2:
            lst_ennemis_classique = [slime, slime, slime, Tireur, Creeper]
        elif 2 < self.level.lvl_actu <= 4:
            lst_ennemis_classique = [slime, Tireur, Creeper]
        else:
            lst_ennemis_classique = [slime, Tireur, Tireur, Creeper]
        
        nb_ennemies = random.randint(1, 6 - self.level.nb_ennemis)
        if nb_ennemies > 6:
            nb_ennemies = 6
        lst_nom = ['ennemi_1', 'ennemi_2', 'ennemi_3', 'ennemi_4', 'ennemi_5', 'ennemi_6']
        for i in range(nb_ennemies):
            postition_desactivé = [k for k, v in salle_actu.depart_ennemi.items() if not v["active"]]
            if postition_desactivé:
                position_aleatoire = random.choice(postition_desactivé)
                salle_actu.depart_ennemi[position_aleatoire]["active"] = True
            choix_classe = random.choice(lst_ennemis_classique)
            nouvelle_ennemi = random.choice(lst_nom)
            nouvelle_ennemi = choix_classe(salle_actu, position_aleatoire, self.level)
            print(f"Ajout d'un ennemi: {nouvelle_ennemi}")
            salle_actu.ennemis.append(nouvelle_ennemi)

    def assigner_caisse(self, salle):
        """assigne des caisses dans une salle"""
        nb_caisse = random.randint(0, 5)
        for i in range(nb_caisse):
            while True:
                x = random.randint(32, L_salle - 48)
                y = random.randint(32, H_salle - 48)
                if random.random() < 0.3:
                    rubis = True
                else:
                    rubis = False
                if not any(caisse.x-16 < x < caisse.x+16 and caisse.y-16 < y < caisse.y+16 for caisse in salle.caisses):
                    if not any(spawn["x"]-16 < x < spawn["x"]+16 and spawn["y"]-16 < y < spawn["y"]+16 for spawn in salle.depart_ennemi.values()):
                        salle.caisses.append(Caisse(x, y, salle, rubis))
                        break

    def assigner_salle_achat(self):
        """Assigne une salle d'achat avec 70% de chance d'apparaître"""
        if random.random() < 0.70:
            salles_random = [s for s in self.salles if s.type == 1]
            if salles_random:
                salle_achat = random.choice(salles_random)
                salle_achat.type = 5
                salle_achat.buff = [random.choice([
                    {"type": "vie", "prix": 5, "sprite": (0, 104, 208, 8, 16, 9)},
                    {"type": "vitesse", "prix": 5, "sprite": (0, 80, 208, 8, 16, 9)},
                    {"type": "cooldown", "prix": 5, "sprite": (0, 88, 208, 8, 16, 9)},
                    {"type": "tir", "prix": 15, "sprite": (0, 96, 208, 8, 16, 9)},
                    {"type": "degat", "prix": 6, "sprite": (0, 112, 208, 8, 16, 9)}
                ]),
                random.choice([
                            {"type": "vie", "prix": 5, "sprite": (0, 104, 208, 8, 16, 9)},
                            {"type": "vitesse", "prix": 5, "sprite": (0, 80, 208, 8, 16, 9)},
                            {"type": "cooldown", "prix": 5, "sprite": (0, 88, 208, 8, 16, 9)},
                            {"type": "tir", "prix": 16, "sprite": (0, 96, 208, 8, 16, 9)},
                            {"type": "degat", "prix": 6, "sprite": (0, 112, 208, 8, 16, 9)}
                        ])
                ]
#verifier que la salle de depart a une porte
    def verifier_porte_salle_depart(self):
        salle_depart = self.salles[0]
        voisins_vides = self.voisins_vides(salle_depart)
        if not voisins_vides:
            voisins_existants = self.voisins_existants(salle_depart)
            if voisins_existants:
                direction, (nx, ny) = random.choice(voisins_existants)
                salle_existante = self.grille[ny][nx]
                if salle_existante is not None:
                    self.ajouter_porte(salle_depart, salle_existante, direction)
        else:
            direction, (nx, ny) = random.choice(voisins_vides)
            nouvelle_salle = Salle(nx, ny)
            self.assigner_ennemis_classique(nouvelle_salle)
            self.assigner_caisse(nouvelle_salle)
            self.ajouter_porte(salle_depart, nouvelle_salle, direction)
            self.salles.append(nouvelle_salle)
            self.grille[ny][nx] = nouvelle_salle

    def voisins_existants(self, salle):
        directions = {
            "Nord": (0, -1),
            "Sud": (0, 1),
            "Ouest": (-1, 0),
            "Est": (1, 0)}
        voisins_existants = []
        for direction, (dx, dy) in directions.items():
            nx, ny = salle.x + dx, salle.y + dy
            if 0 <= nx < L_grille and 0 <= ny < H_grille:
                if self.grille[ny][nx] is not None:
                    voisins_existants.append((direction, (nx, ny)))
        return voisins_existants
#gere le joueur et ses actions
class Joueur:
    def __init__(self, salle_depart_x, salle_depart_y, donjon, buff={"degat": 0, "vitesse": 0, "cooldown": 0, "tir": 0}):
        #buff
        self.buff = buff
        #salle
        self.grille_x = salle_depart_x
        self.grille_y = salle_depart_y
        #deplacement
        self.coo_x = L_salle//2
        self.coo_y = H_salle//2
        self.vitesse = 2 +0.25*self.buff["vitesse"]
        #tirs
        self.degat = 1 + self.buff["degat"]
        self.direction = "Sud"
        self.projectiles = []
        self.cooldown_tir = 15 - 0.4*self.buff["cooldown"]
        self.dernier_tir = 0 
        #autre
        self.vie = 3
        self.cle_recuperee = False
        self.donjon = donjon
        self.rubis_recuperes = 0
        #animation
        self.joueur_frame = 0
        self.animation = 0
        self.en_mouvement = False
        self.touche = False
        self.dernier_touche = 0
        
    def haut(self, salle_actuelle):#fleche haut
        self.coo_y -= self.vitesse
        self.verifier_position(salle_actuelle)
        self.direction = "Nord"
        self.en_mouvement = True
    
    def gauche(self, salle_actuelle):#fleche gauche
        self.coo_x -= self.vitesse
        self.verifier_position(salle_actuelle)
        self.direction = "Ouest"
        self.en_mouvement = True
    
    def droite(self, salle_actuelle):#fleche droite
        self.coo_x += self.vitesse
        self.verifier_position(salle_actuelle)
        self.direction = "Est"
        self.en_mouvement = True
    
    def bas(self, salle_actuelle):#fleche bas
        self.coo_y += self.vitesse
        self.verifier_position(salle_actuelle)
        self.direction = "Sud"
        self.en_mouvement = True
        
    def verifier_position(self, salle_actuelle):
        """on verifie que le joueur reste dans l'ecran et/ou qu'il change de salle"""
        # Passage à droite
        if self.coo_x > L_salle-16:
            if self.coo_y > (H_salle//2)-8 and self.coo_y < (H_salle//2)+8 and salle_actuelle.portes["Est"] and salle_actuelle.ennemis == []:
                if salle_actuelle.portes_type["Est"] == 3 and not self.cle_recuperee:
                    self.coo_x = L_salle-16
                else:
                    self.grille_x += 1
                    self.coo_x = 24
                    salle_actuelle.portes_visitees["Est"] = True
                    self.donjon.grille[self.grille_y][self.grille_x].portes_visitees["Ouest"] = True
            else:
                self.coo_x = L_salle-16
        
        # Passage à gauche
        if self.coo_x < 16:
            if self.coo_y > (H_salle//2)-8 and self.coo_y < (H_salle//2)+8 and salle_actuelle.portes["Ouest"] and salle_actuelle.ennemis == []:
                if salle_actuelle.portes_type["Ouest"] == 3 and not self.cle_recuperee:
                    self.coo_x = 16
                else:
                    self.grille_x -= 1
                    self.coo_x = L_salle-24
                    salle_actuelle.portes_visitees["Ouest"] = True
                    self.donjon.grille[self.grille_y][self.grille_x].portes_visitees["Est"] = True
            else:
                self.coo_x = 16
        
        # Passage en bas
        if self.coo_y > H_salle-16:
            if self.coo_x > (L_salle//2)-8 and self.coo_x < (L_salle//2)+8 and salle_actuelle.portes["Sud"] and salle_actuelle.ennemis == []:
                if salle_actuelle.portes_type["Sud"] == 3 and not self.cle_recuperee:
                    self.coo_y = H_salle-16
                else:
                    self.grille_y += 1
                    self.coo_y = 24
                    salle_actuelle.portes_visitees["Sud"] = True
                    self.donjon.grille[self.grille_y][self.grille_x].portes_visitees["Nord"] = True
            else:
                self.coo_y = H_salle-16
        
        # Passage en haut
        if self.coo_y < 16:
            if self.coo_x > (L_salle//2)-8 and self.coo_x < (L_salle//2)+8 and salle_actuelle.portes["Nord"] and salle_actuelle.ennemis == []:
                if salle_actuelle.portes_type["Nord"] == 3 and not self.cle_recuperee:
                    self.coo_y = 16
                else:
                    self.grille_y -= 1
                    self.coo_y = H_salle-24
                    salle_actuelle.portes_visitees["Nord"] = True
                    self.donjon.grille[self.grille_y][self.grille_x].portes_visitees["Sud"] = True
            else:
                self.coo_y = 16
    
    def update(self, salle_actuelle):
        self.mettre_a_jour_tirs()
        for ennemi in salle_actuelle.ennemis:
            if isinstance(ennemi, Tireur) or isinstance(ennemi, boss_1):  
                for projectile in ennemi.projectiles:
                    if self.est_touche_par_projectile(projectile):
                        self.vie -= 1
                        projectile.actif = False
        if salle_actuelle.rubis and salle_actuelle.rubis.est_touche_par_joueur(self):
            self.rubis_recuperes += 1
            salle_actuelle.rubis.disponible = False
                        
    def est_touche_par_projectile(self, projectile):
        """ Vérifie si un projectile ennemi touche le joueur """
        if self.coo_x - 7 < projectile.x < self.coo_x + 7 and self.coo_y - 7 < projectile.y < self.coo_y + 7:
            self.touche = True
            self.dernier_touche = pyxel.frame_count
            return True
        return False
        
    def tirer(self):
        """Tire un projectile """
        if pyxel.frame_count - self.dernier_tir >= self.cooldown_tir:
            proj_x = self.coo_x 
            proj_y = self.coo_y - 6
            angle = 0

            if self.direction == "Nord":
                angle = -math.pi / 2
            elif self.direction == "Sud":
                angle = math.pi / 2
            elif self.direction == "Ouest":
                angle = math.pi
            elif self.direction == "Est":
                angle = 0

            self.projectiles.append(Projectile(proj_x, proj_y, self.direction, angle, 4, self.degat))

            if self.buff["tir"] >= 1:
                tir_2 = angle + math.radians(25)
                self.projectiles.append(Projectile(proj_x, proj_y, self.direction, tir_2, 4, self.degat))
            if self.buff["tir"] >= 2:
                tir_3 = angle + math.radians(-25)
                self.projectiles.append(Projectile(proj_x, proj_y, self.direction, tir_3, 4, self.degat))
            if self.buff["tir"] >= 3:
                tir_4 = angle + math.radians(45)
                self.projectiles.append(Projectile(proj_x, proj_y, self.direction, tir_4, 4, self.degat))
            if self.buff["tir"] >= 4:
                tir_5 = angle + math.radians(-45)
                self.projectiles.append(Projectile(proj_x, proj_y, self.direction, tir_5, 4, self.degat))

            self.dernier_tir = pyxel.frame_count
            pyxel.play(0, 17)

    def mettre_a_jour_tirs(self):
        """Met à jour les projectiles et supprime ceux qui sont inactifs."""
        for projectile in self.projectiles:
            projectile.update_joueur()
        
        self.projectiles = [p for p in self.projectiles if p.actif]
        
    def dessiner(self):
        self.animation += 10
        if self.animation % 10 == 0:
            self.joueur_frame = (self.joueur_frame + 1) % 9
        if self.animation >= 90:
            self.animation = 0
        
        if self.touche and pyxel.frame_count - self.dernier_touche < 10:
            if self.direction == "Est" :
                pyxel.blt(self.coo_x-8, self.coo_y-14, 1, 144, 48, 16, 16, 1)
            elif self.direction == "Sud" :
                pyxel.blt(self.coo_x-8, self.coo_y-14, 1, 144, 0, 16, 16, 1)
            elif self.direction == "Nord" :
                pyxel.blt(self.coo_x-8, self.coo_y-14, 1, 144, 16, 16, 16, 1)
            elif self.direction == "Ouest" :
                pyxel.blt(self.coo_x-8, self.coo_y-14, 1, 144, 32, 16, 16, 1)
        else:
            self.touche = False
            if self.direction == "Est" :
                if self.en_mouvement:
                    pyxel.blt(self.coo_x-8, self.coo_y-14, 1, self.joueur_frame*16, 48, 16, 16, 1)
                else:
                    pyxel.blt(self.coo_x-8, self.coo_y-14, 1, 0, 48, 16, 16, 1)
            elif self.direction == "Sud" :
                if self.en_mouvement:
                    pyxel.blt(self.coo_x-8, self.coo_y-14, 1, self.joueur_frame*16, 0, 16, 16, 1)
                else:
                    pyxel.blt(self.coo_x-8, self.coo_y-14, 1, 0, 0, 16, 16, 1)
            elif self.direction == "Nord" :
                if self.en_mouvement:
                    pyxel.blt(self.coo_x-8, self.coo_y-14, 1, self.joueur_frame*16, 16, 16, 16, 1)
                else:
                    pyxel.blt(self.coo_x-8, self.coo_y-14, 1, 0, 16, 16, 16, 1)
            elif self.direction == "Ouest" :
                if self.en_mouvement:
                    pyxel.blt(self.coo_x-8, self.coo_y-14, 1, self.joueur_frame*16, 32, 16, 16, 1)
                else:
                    pyxel.blt(self.coo_x-8, self.coo_y-14, 1, 0, 32, 16, 16, 1)
        for i in range(0, self.vie):
            pyxel.blt(4 + 16*i, 4, 1, 160, 0, 8, 8, 1)
        if self.cle_recuperee:
            pyxel.blt(4, 20, 0, 24, 136, 8, 8, 1)
            
        for projectile in self.projectiles:
            projectile.dessiner_tir_joueur()
    
    def detecter_mouvement(self):
        """ Vérifie si une touche directionnelle est pressée """
        if pyxel.btn(pyxel.KEY_UP) or pyxel.btn(pyxel.KEY_DOWN) or pyxel.btn(pyxel.KEY_LEFT) or pyxel.btn(pyxel.KEY_RIGHT):
            self.en_mouvement = True
        else:
            self.en_mouvement = False
            self.joueur_frame = 0

    def acheter_buff(self, salle_actuelle):
        if salle_actuelle.type == 5:
            i = 0
            for buff in salle_actuelle.buff:
                if buff and self.rubis_recuperes >= buff["prix"]:
                    if L_salle//2 - 20 + i * 30 - 8 < self.coo_x < L_salle//2 - 20 + i * 30 + 8 and H_salle//2 - 16 < self.coo_y < H_salle//2 + 16:
                        self.rubis_recuperes -= buff["prix"]
                        if buff["type"] == "vie":
                            self.vie += 1
                        elif buff["type"] == "vitesse":
                            self.buff["vitesse"] += 1
                            self.vitesse += 0.25
                        elif buff["type"] == "cooldown":
                            self.buff["cooldown"] += 1
                            self.cooldown_tir -= 0.4
                        elif buff["type"] == "tir":
                            self.buff["tir"] += 1
                        elif buff["type"] == "degat":
                            self.buff["degat"] += 0.5
                            self.degat += 0.5
                        salle_actuelle.buff[i] = None
                i += 1

#gere le slime et ses actions
class slime:

    def __init__(self, obj_salle, num_spawn, level):
        self.spawn = obj_salle.depart_ennemi[num_spawn]
        self.x, self.y = self.spawn["x"], self.spawn["y"]
        self.level = level
        self.vie = 2 + level.pv_ennemi_slime
        self.vitesse = 5 + self.level.vitesse_slime
        self.cooldown_mouv = 20 - self.level.cooldown_slime
        self.dernier_mouv = 0
        self.projectiles = []
        self.salle = obj_salle
        
        self.direction = "sud"
        self.touche = False
        self.dernier_touche = 0
        
    def update(self, joueur):
        if pyxel.frame_count - self.dernier_mouv >= self.cooldown_mouv:
            r = random.choice(["Nord","Sud","Ouest","Est"])
            self.direction = r
            if r == "Nord":
                self.y -= self.vitesse
                if self.y < 24:
                    self.y = 24
            if r == "Sud":
                self.y += self.vitesse
                if self.y > H_salle-24:
                    self.y = H_salle-24
            if r == "Ouest":
                self.x -= self.vitesse
                if self.x < 24:
                    self.x = 24
            if r == "Est":
                self.x += self.vitesse
                if self.x > L_salle-24:
                    self.x = L_salle-24
            if self.level.lvl_actu > 5:
                self.tirer()
            
            self.dernier_mouv = pyxel.frame_count

            for projectile in list(self.projectiles):  
                projectile.update_ennemi()
            
            self.projectiles = [p for p in self.projectiles if p.actif]
    
    def tirer(self):
        """Tire un projectile """
        proj_x = self.x 
        proj_y = self.y
        self.projectiles.append(Projectile(proj_x, proj_y, self.direction, None, 8))
        pyxel.play(0, 17)

    def est_touche_par_tir(self, projectile):
        """ Vérifie si le projectile touche le slime """
        if self.x-8 < projectile.x < self.x+8 and self.y-8 < projectile.y < self.y+8:
            self.touche = True
            self.dernier_touche = pyxel.frame_count
            return True
        return False
        
    def est_touche_par_joueur(self, joueur):
        if self.x-8 < joueur.coo_x < self.x+8 and self.y-8 < joueur.coo_y < self.y+8:
            joueur.touche = True
            joueur.dernier_touche = pyxel.frame_count
            return True
        return False
        
    
    def dessiner(self):
        if self.salle.type == 3:
            pyxel.pal(11, 12)
            pyxel.pal(3, 5)

        if self.touche and pyxel.frame_count - self.dernier_touche < 10:
            if self.direction == "Est" :
                pyxel.blt(self.x -8,self.y-8, 1, 112, 64, 16, 16, 1)
            elif self.direction == "Sud" :
                pyxel.blt(self.x -8,self.y-8, 1, 48, 64, 16, 16, 1)
            elif self.direction == "Nord" :
                pyxel.blt(self.x -8,self.y-8, 1, 48, 80, 16, 16, 1)
            elif self.direction == "Ouest" :
                pyxel.blt(self.x -8,self.y-8, 1, 112, 80, 16, 16, 1)
        else:
            self.touche = False
            if self.direction == "Est" :
                pyxel.blt(self.x -8,self.y-8, 1, 64, 64, 16, 16, 1)
            elif self.direction == "Sud" :
                pyxel.blt(self.x -8,self.y-8, 1, 0, 64, 16, 16, 1)
            elif self.direction == "Nord" :
                pyxel.blt(self.x -8,self.y-8, 1, 0, 80, 16, 16, 1)
            elif self.direction == "Ouest" :
                pyxel.blt(self.x -8,self.y-8, 1, 64, 80, 16, 16, 1)
        
        for projectile in self.projectiles:
            projectile.dessiner_tir_ennemis()
        pyxel.pal()
#gere le tireur et ses actions
class Tireur:
    def __init__(self, obj_salle, num_spawn, level):
        self.spawn = obj_salle.depart_ennemi[num_spawn]
        self.x, self.y = self.spawn["x"], self.spawn["y"]
        self.level = level
        self.vie = self.level.pv_ennemi_tireur
        self.cooldown_tir = 70 - self.level.cooldown_tireur
        self.dernier_tir = 0
        self.projectiles = []
        self.salle = obj_salle
        
        self.direction = "sud"
        self.touche = False
        self.dernier_touche = 0

    def update(self, joueur):
        if pyxel.frame_count - self.dernier_tir > self.cooldown_tir:
            self.tirer(joueur)
            pyxel.play(0, 17)
            self.dernier_tir = pyxel.frame_count
            
        for projectile in list(self.projectiles):  
            projectile.update_ennemi()
            
        self.projectiles = [p for p in self.projectiles if p.actif]
        
    def tirer(self, joueur):
        dx = joueur.coo_x - self.x
        dy = joueur.coo_y - self.y
        distance = math.sqrt(dx**2 + dy**2)
        
        if distance == 0:
            return
        if abs(dx) > abs(dy):
            if dx > 0:
                self.direction = "Est"
            else:
                self.direction = "Ouest"
        else:
            if dy > 0:
                self.direction = "Sud"
            else:
                self.direction = "Nord"
        angle = math.atan2(dy, dx)
        vitesse_projectile = 2
        self.projectiles.append(Projectile(self.x, self.y, None, angle, vitesse_projectile))
        if self.level.lvl_actu > 3:
            self.projectiles.append(Projectile(self.x, self.y, None, angle + math.radians(45), vitesse_projectile))
            self.projectiles.append(Projectile(self.x, self.y, None, angle - math.radians(45), vitesse_projectile))
        recul_distance = 8
        self.x -= recul_distance * math.cos(angle)
        self.y -= recul_distance * math.sin(angle)
        if self.x < 24:
            self.x = 24
        if self.x > L_salle- 24:
            self.x = L_salle- 24
        if self.y < 24:
            self.y = 24
        if self.y > H_salle- 24:
            self.y = H_salle- 24
        
    def est_touche_par_tir(self, projectile):
        if self.x - 7 < projectile.x < self.x + 7 and self.y - 7 < projectile.y < self.y + 9:
            self.touche = True
            self.dernier_touche = pyxel.frame_count
            return True
        return False

    def est_touche_par_joueur(self, joueur):
        if self.x - 7 < joueur.coo_x < self.x + 7 and self.y - 7 < joueur.coo_y < self.y + 9:
            joueur.touche = True
            joueur.dernier_touche = pyxel.frame_count
            return True
        return False

    def dessiner(self):
        if self.salle.type == 3:
            pyxel.pal(14, 6)
            pyxel.pal(8, 12)
            pyxel.pal(2, 5)
        if self.touche and pyxel.frame_count - self.dernier_touche < 10:
            if self.direction == "Est" :
                pyxel.blt(self.x -8,self.y-8, 1, 48, 112, 16, 16, 1)
            elif self.direction == "Sud" :
                pyxel.blt(self.x -8,self.y-8, 1, 48, 96, 16, 16, 1)
            elif self.direction == "Nord" :
                pyxel.blt(self.x -8,self.y-8, 1, 16, 96, 16, 16, 1)
            elif self.direction == "Ouest" :
                pyxel.blt(self.x -8,self.y-8, 1, 16, 112, 16, 16, 1)
        else:
            self.touche = False
            if self.direction == "Est" :
                pyxel.blt(self.x -8,self.y-8, 1, 32, 112, 16, 16, 1)
            elif self.direction == "Sud" :
                pyxel.blt(self.x -8,self.y-8, 1, 32, 96, 16, 16, 1)
            elif self.direction == "Nord" :
                pyxel.blt(self.x -8,self.y-8, 1, 0, 96, 16, 16, 1)
            elif self.direction == "Ouest" :
                pyxel.blt(self.x -8,self.y-8, 1, 0, 112, 16, 16, 1)
        pyxel.pal()
        for projectile in self.projectiles:
            projectile.dessiner_tir_ennemis()
#gere le creeper et ses actions
class Creeper:
    def __init__(self, obj_salle, num_spawn, level):
        self.spawn = obj_salle.depart_ennemi[num_spawn]
        self.x, self.y = self.spawn["x"], self.spawn["y"]
        self.level = level
        self.vie = 1  # Le creeper a une vie unique
        self.vitesse = 2  # Vitesse du creeper
        self.salle = obj_salle
        self.explosion_en_cours = False
        self.temps_explosion = 0
        self.taille_explosion = 32
        self.taille_creeper = 8
        self.direction = "sud"

    def update(self, joueur):
        if self.explosion_en_cours:
            if pyxel.frame_count - self.temps_explosion > 15:
                self.exploser(joueur)
            return

        dx = joueur.coo_x - self.x
        dy = joueur.coo_y - self.y
        distance = math.sqrt(dx**2 + dy**2)

        if distance < self.taille_explosion//2:
            self.explosion_en_cours = True
            self.temps_explosion = pyxel.frame_count
        else:
            angle = math.atan2(dy, dx)
            self.x += self.vitesse * math.cos(angle)
            self.y += self.vitesse * math.sin(angle)

        if abs(dx) > abs(dy):
            if dx > 0:
                self.direction = "Est"
            else:
                self.direction = "Ouest"
        else:
            if dy > 0:
                self.direction = "Sud"
            else:
                self.direction = "Nord"

    def exploser(self, joueur):
        if self.x - (self.taille_explosion // 2 + 4)< joueur.coo_x < self.x + (self.taille_explosion // 2 + 4 )and self.y - (self.taille_explosion // 2 + 4)< joueur.coo_y < self.y + (self.taille_explosion // 2 + 4):
            joueur.vie -= 1
        self.salle.ennemis.remove(self)

    def est_touche_par_tir(self, projectile):
        if self.x - 5 < projectile.x < self.x + 5 and self.y - 5 < projectile.y < self.y + 5:
            self.touche = True
            self.dernier_touche = pyxel.frame_count
            return True
        return False

    def est_touche_par_joueur(self, joueur):
        if self.x - 5 < joueur.coo_x < self.x + 5 and self.y - 5 < joueur.coo_y < self.y + 5:
            joueur.touche = True
            joueur.dernier_touche = pyxel.frame_count
            return True
        return False

    def dessiner(self):
        if self.explosion_en_cours:
            pyxel.blt(self.x - self.taille_explosion // 2 , self.y - self.taille_explosion // 2, 1, 80, 112, self.taille_explosion, self.taille_explosion, 1)
        else:
            pyxel.blt(self.x - self.taille_creeper // 2, self.y - self.taille_creeper // 2, 1, 64, 96, self.taille_creeper, self.taille_creeper, 1)
#gere le boss et ses actions
class boss_1:
    def __init__(self, level):
        #attributs pour la position
        self.x, self.y = L_salle // 2, H_salle // 2
        self.level = level
        #attributs pour la vie
        self.vie =  5 + self.level.pv_boss
        #attributs pour le mouvement
        self.vitesse = 10 + self.level.vitesse_boss
        self.cooldown_mouv = 15 - self.level.cooldown_mouv_boss 
        self.dernier_mouv = 0
        self.direction = "Sud"
        #attributs pour le tir
        self.cooldown_tir = 70 - self.level.cooldown_tir_boss
        self.dernier_tir = 0
        self.projectiles = []
        #attributs pour l'invocation
        self.cooldown_invocation = 600 - self.level.cooldown_invocation_boss
        self.dernier_invocation = 0
        self.salle = None
        #attributs pour l'animation
        self.animation_tir = False
        self.dernier_tir_animation = 0

    def update(self, joueur):
        # Mouvement aléatoire
        if pyxel.frame_count - self.dernier_mouv >= self.cooldown_mouv:
            r = random.choice(["Nord", "Sud", "Ouest", "Est"])
            if r == "Nord":
                self.y -= self.vitesse
                self.direction = "Nord"
                if self.y < 24:
                    self.y = 24
            if r == "Sud":
                self.y += self.vitesse
                self.direction = "Sud"
                if self.y > H_salle - 24:
                    self.y = H_salle - 24
            if r == "Ouest":
                self.x -= self.vitesse
                self.direction = "Ouest"
                if self.x < 24:
                    self.x = 24
            if r == "Est":
                self.x += self.vitesse
                self.direction = "Est"
                if self.x > L_salle - 24:
                    self.x = L_salle - 24
            self.dernier_mouv = pyxel.frame_count
        # animation de tir
        if self.animation_tir and pyxel.frame_count - self.dernier_tir_animation > 5:
                self.animation_tir = False

        # Tirer des projectiles
        if pyxel.frame_count - self.dernier_tir >= self.cooldown_tir:
            self.tirer(joueur)
            self.dernier_tir = pyxel.frame_count

        # Mise à jour des projectiles
        for projectile in list(self.projectiles):
            projectile.update_ennemi()

        self.projectiles = [p for p in self.projectiles if p.actif]

        if len(self.salle.ennemis) <= 1 and self.level.lvl_actu <= 2:
            if pyxel.frame_count - self.dernier_invocation >= self.cooldown_invocation:
                self.invocation()
                self.dernier_invocation = pyxel.frame_count
        elif len(self.salle.ennemis) <= 2 and  2 < self.level.lvl_actu <= 4:
            if pyxel.frame_count - self.dernier_invocation >= self.cooldown_invocation:
                self.invocation()
                self.dernier_invocation = pyxel.frame_count
        elif len(self.salle.ennemis) <= 4 and 4 < self.level.lvl_actu :
            if pyxel.frame_count - self.dernier_invocation >= self.cooldown_invocation:
                self.invocation()
                self.dernier_invocation = pyxel.frame_count

    def tirer(self, joueur):
        dx = joueur.coo_x - self.x
        dy = joueur.coo_y - self.y
        angle = math.atan2(dy, dx)
        vitesse_projectile = 2

        # Tir principal
        self.projectiles.append(Projectile(self.x, self.y, None, angle, vitesse_projectile))
        tir_2 = angle + math.radians(45)
        self.projectiles.append(Projectile(self.x, self.y, None, tir_2, vitesse_projectile))
        tir_3 = angle - math.radians(45)
        self.projectiles.append(Projectile(self.x, self.y, None, tir_3, vitesse_projectile))
        if self.level.lvl_actu > 3:
            tir_4 = angle + math.radians(90)
            self.projectiles.append(Projectile(self.x, self.y, None, tir_4, vitesse_projectile))
            tir_5 = angle - math.radians(90)
            self.projectiles.append(Projectile(self.x, self.y, None, tir_5, vitesse_projectile))

        # son de tir
        pyxel.play(0, 17)
        # animation apès tir
        self.animation_tir = True
        self.dernier_tir_animation = pyxel.frame_count

    def invocation(self):
        spawns = [key for key, spawn in self.salle.depart_ennemi.items()]
        if self.level.lvl_actu < 3:
            lst_ennemis_classique = [slime, slime, slime, Tireur, Creeper]
            nb_invoc = random.randint(1, 2)
        elif self.level.lvl_actu < 6:
            lst_ennemis_classique = [slime, Tireur, Creeper]
            nb_invoc = random.randint(2, 4)
        else :
            lst_ennemis_classique = [slime, Tireur, Tireur, Creeper, Creeper, Creeper]
            nb_invoc = random.randint(3, 7)
        for _ in range(nb_invoc):
            spawn_key = random.choice(spawns)
            self.salle.depart_ennemi[spawn_key]["active"] = True
            choix_classe = random.choice(lst_ennemis_classique)
            invoc = choix_classe(self.salle, spawn_key, self.level)
            self.salle.ennemis.append(invoc)

    def est_touche_par_tir(self, projectile):
        return self.x - 5 < projectile.x < self.x + 5 and self.y - 6 < projectile.y < self.y + 9

    def est_touche_par_joueur(self, joueur):
        return self.x - 5 < joueur.coo_x < self.x + 5 and self.y - 6 < joueur.coo_y < self.y + 9

    def dessiner(self):
        #boss
        if self.animation_tir:
            pyxel.blt(self.x - 8, self.y - 8, 1, 16, 144, 16, 16, 1)
        else:
            pyxel.blt(self.x - 8, self.y - 8, 1, 0, 144, 16, 16, 1)
        #projectiles
        for projectile in self.projectiles:
            projectile.dessiner_tir_ennemis()
        # Dessiner la barre de vie
        self.dessiner_barre_pv()

    def dessiner_barre_pv(self):
        largeur_barre = 100
        hauteur_barre = 3
        x_barre = (L_salle - largeur_barre) // 2
        y_barre = H_salle - 8
        vie_max = 5 + self.level.pv_boss
        pourcentage_vie = self.vie / vie_max
        largeur_vie = int(largeur_barre * pourcentage_vie)
        pyxel.rect(x_barre, y_barre, largeur_barre, hauteur_barre, pyxel.COLOR_RED)
        pyxel.rect(x_barre, y_barre, largeur_vie, hauteur_barre, pyxel.COLOR_GREEN)

#gere tout les projectiles
class Projectile:
    def __init__(self, x, y, direction, angle, vitesse_tir, degat = 1):
        self.x = x
        self.y = y
        self.direction = direction
        self.angle = angle
        self.vitesse = vitesse_tir
        self.degat = degat
        self.actif = True

    def update_joueur(self):
        if self.angle is not None:
            self.x += self.vitesse * math.cos(self.angle)
            self.y += self.vitesse * math.sin(self.angle)
        else:
            if self.direction == "Nord":
                self.y -= self.vitesse
            
            elif self.direction == "Sud":
                self.y += self.vitesse
            
            elif self.direction == "Ouest":
                self.x -= self.vitesse
            
            elif self.direction == "Est":
                self.x += self.vitesse

        if self.x < 12 or self.x > L_salle-12 or self.y < 12 or self.y > H_salle-12:
            self.actif = False
            pyxel.play(0, 18)
    
    def update_ennemi(self):
        if self.angle is not None:
            self.x += self.vitesse * math.cos(self.angle)
            self.y += self.vitesse * math.sin(self.angle)
        else : 
            if self.direction == "Nord":
                self.y -= self.vitesse
            elif self.direction == "Sud":
                self.y += self.vitesse
            elif self.direction == "Ouest":
                self.x -= self.vitesse
            elif self.direction == "Est":
                self.x += self.vitesse
    
        if self.x < 12 or self.x > L_salle - 12 or self.y < 12 or self.y > H_salle - 12:
            self.actif = False
            pyxel.play(0, 18)

            
    def dessiner_tir_joueur(self):
        if self.x < 14 or self.x > L_salle-14 or self.y < 14 or self.y > H_salle-14:
            pyxel.blt(self.x - 4, self.y - 4, 1, 168, 16, 8, 8, 1)
        else:
            pyxel.blt(self.x - 4, self.y - 4, 1, 160, 16, 8, 8, 1)
    def dessiner_tir_ennemis(self):
        if self.x < 14 or self.x > L_salle-14 or self.y < 14 or self.y > H_salle-14:
            pyxel.blt(self.x - 4, self.y - 4, 1, 168, 32, 8, 8, 1)
        else:
            pyxel.blt(self.x - 4, self.y - 4, 1, 160, 32, 8, 8, 1)
#gere les caisse et leur influence
class Caisse:
    def __init__(self, x, y, salle, rubis):
        self.x = x
        self.y = y
        self.vie = 1
        self.salle = salle
        self.rubis = rubis

    def dessiner(self):
        if self.salle.type == 3: 
            pyxel.blt(self.x-8, self.y-8, 0, 64, 144, 16, 16, 1)
        else:
            pyxel.blt(self.x-8, self.y-8, 0, 64, 128, 16, 16, 1)

    def est_touche_par_projectile(self, projectile):
        if self.x-9 < projectile.x < self.x + 9 and self.y-9 < projectile.y < self.y + 9:
            return True
        return False

    def est_touche_par_ennemi(self, ennemi):
        if self.x-8 < ennemi.x < self.x + 8 and self.y-8 < ennemi.y < self.y + 8:
            return True
        return False

    def est_touche_par_joueur(self, joueur):
        if self.x-8 < joueur.coo_x < self.x + 8 and self.y-8 < joueur.coo_y < self.y + 8:
            return True
        return False
#gere la musique
class Musique:
    def __init__(self):
        self.musique_active = True
        self.musiques = {
            "menu": 0,
            "jeu": 1,
            "boss": 2
        }
        self.musique_actuelle = None

    def jouer_musique(self, type_musique):
        if self.musique_active:
            if self.musique_actuelle != self.musiques[type_musique]:
                pyxel.playm(self.musiques[type_musique], loop=True)
                self.musique_actuelle = self.musiques[type_musique]

    def arreter_musique(self):
        pyxel.stop()
        self.musique_actuelle = None

    def activation_musique(self):
        self.musique_active = not self.musique_active
        if self.musique_active:
            self.jouer_musique("menu")
        else:
            self.arreter_musique()

class App:
    def __init__(self, level = 0):
        pyxel.init(L_salle, H_salle, title="Oscaar")
        pyxel.load("Oscaar.pyxres")
        self.lvl_modif = Lvl_modif(level)
        self.donjon = Donjon(self.lvl_modif)
        self.joueur = Joueur(self.donjon.salles[0].x, self.donjon.salles[0].y, self.donjon)
        self.musique = Musique()
        self.etat = "menu"
        self.musique.jouer_musique("menu")
        self.niveau_actuel = level
        self.temps_transition = 0
        pyxel.run(self.update, self.draw)

    def update(self):
        if self.etat == "menu":
            self.update_menu()
        elif self.etat == "jeu":
            self.update_jeu()
        elif self.etat == "transition":
            self.update_transition()
        elif self.etat == "fin":
            self.update_fin()
        elif self.etat == "menu_jeu":
            self.update_menu_jeu()

    def update_menu(self):
        pyxel.mouse(True)
        if pyxel.btnp(pyxel.MOUSE_BUTTON_LEFT):
            if self.bouton_clique(L_salle//2 -16, 48, 32, 20):
                self.niveau_actuel = 0
                self.lvl_modif = Lvl_modif(self.niveau_actuel)
                self.donjon = Donjon(self.lvl_modif)
                self.joueur = Joueur(self.donjon.salles[0].x, self.donjon.salles[0].y, self.donjon)
                self.etat = "jeu"
            elif self.bouton_clique(L_salle//2 -16, 80, 32, 20):
                self.etat = "jeu"
            elif self.bouton_clique(L_salle//2 -16, 124, 32, 20):
                pyxel.quit()
            elif self.bouton_clique(L_salle - 36, H_salle - 36, 16, 16):
                self.musique.activation_musique()
    
    def update_reglages(self):
        pyxel.mouse(True)
        if pyxel.btnp(pyxel.KEY_ESCAPE):
            self.etat = "menu"
    
    def update_transition(self):
        if pyxel.frame_count - self.temps_transition > 120:
            self.etat = "jeu"
        
    def update_jeu(self):
        pyxel.mouse(False)
        if self.joueur.vie <= 0:
            self.musique.arreter_musique()
            if pyxel.btnp(pyxel.KEY_R):
                self.recommencer_jeu()
            return
        
        salle_actuelle = next(s for s in self.donjon.salles if s.x == self.joueur.grille_x and s.y == self.joueur.grille_y)

        if pyxel.btnp(pyxel.KEY_E) and not salle_actuelle.ennemis:
            self.etat = "menu_jeu"
            return
        
        if salle_actuelle.type == 3:
            self.musique.jouer_musique("boss")
            salle_actuelle.check_boss_defeat()
        else:
            self.musique.jouer_musique("jeu")

        self.joueur.update(salle_actuelle)
        
        if pyxel.btn(pyxel.KEY_UP):  #deplacement haut
            self.joueur.haut(salle_actuelle)
        elif pyxel.btn(pyxel.KEY_DOWN):  #deplacement bas
            self.joueur.bas(salle_actuelle)
        elif pyxel.btn(pyxel.KEY_LEFT):  #deplacement gauche
            self.joueur.gauche(salle_actuelle)
        elif pyxel.btn(pyxel.KEY_RIGHT):  #deplacement droite
            self.joueur.droite(salle_actuelle)
        else :
            self.joueur.en_mouvement = False
        
        if pyxel.btnp(pyxel.KEY_SPACE):  # ESPACE pour tirer
            self.joueur.tirer()

        if pyxel.btnp(pyxel.KEY_A):  # Touche A pour acheter un buff
            self.joueur.acheter_buff(salle_actuelle)
            
        if salle_actuelle.type == 2 and salle_actuelle.cle_disponible:
            if L_salle//2-6 < self.joueur.coo_x < L_salle//2+6 and H_salle//2-6 < self.joueur.coo_y < H_salle//2+6:
                self.joueur.cle_recuperee = True
                salle_actuelle.cle_disponible = False

        if salle_actuelle.type == 4 and salle_actuelle.detecter_collision_fin(self.joueur):
            self.etat = "fin"
                
        if salle_actuelle.porte_de_sortie:
            if (L_salle//2 - 8 < self.joueur.coo_x < L_salle//2 + 8 and
                H_salle//2 - 8 < self.joueur.coo_y < H_salle//2 + 8):
                self.niveau_suivant()

        salle_actuelle.Ennemis_update(self.joueur)
        salle_actuelle.Caisse_update(self.joueur)

    def update_menu_jeu(self):
        pyxel.mouse(True)
        if pyxel.btnp(pyxel.MOUSE_BUTTON_LEFT):
            if self.bouton_clique(L_salle//2 -16, 80, 32, 20):
                self.etat = "jeu"
            elif self.bouton_clique(L_salle//2 -16, 48, 32, 20):
                self.recommencer_jeu()
                self.etat = "jeu"
            elif self.bouton_clique(L_salle//2 -16, 124, 32, 20):
                pyxel.quit()
            elif self.bouton_clique(L_salle - 36, H_salle - 36, 16, 16):
                self.musique.activation_musique()



    def update_fin(self):
        if pyxel.btnp(pyxel.KEY_ESCAPE):
            self.etat = "menu"
    
    def draw(self):
        pyxel.cls(0)
        if self.etat == "menu":
            self.draw_menu()
        elif self.etat == "jeu":
            self.draw_jeu()
        elif self.etat == "transition":
            self.draw_transition()
        elif self.etat == "fin":
            self.draw_fin()
        elif self.etat == "menu_jeu":
            self.draw_menu_jeu()

    def draw_menu(self):
        pyxel.blt(0, 0, 0, 192, 0, 16, 16, 1)#coin haut g
        
        for i in range((L_salle-32)//32):#mur haut
            pyxel.blt(16+(i*32), 0, 0, 208, 0, 32, 16, 1)
        
        pyxel.blt(L_salle-16, 0, 0, 240, 0, 16, 16, 1)#coin haut droit
        
        for j in range((H_salle-32)//32):#mur gauche
            pyxel.blt(0, 16+(j*32), 0, 192, 16, 16, 32, 1)
        
        pyxel.blt(0, H_salle-16, 0, 192, 48, 16, 16, 1)#coin bas gauche
        
        for k in range((L_salle-32)//32):#mur bas
            pyxel.blt(16+(k*32), H_salle-16, 0, 208, 48, 32, 16, 1)
        
        pyxel.blt(L_salle-16, H_salle-16, 0, 240, 48, 16, 16, 1)#coin bas droite
        
        for l in range((H_salle-32)//32):#mur droite
            pyxel.blt(L_salle-16, 16+(l*32), 0, 240, 16, 16, 32, 1)
            
        for n in range((L_salle-32)//32):
            for m in range((H_salle-32)//32):#terrain
                pyxel.blt(16+(n*32), 16+(m*32), 0, 208, 16, 32, 32)
        pyxel.blt(L_salle//2 -16, 48, 0, 192, 64, 32, 16, 1)
        pyxel.blt(L_salle//2 -16, 124, 0, 192, 80, 32, 16, 1)
        self.dessiner_bouton_musique(L_salle - 36, H_salle - 36)

    def draw_menu_jeu(self):
        pyxel.blt(0, 0, 0, 192, 0, 16, 16, 1)#coin haut g
        
        for i in range((L_salle-32)//32):#mur haut
            pyxel.blt(16+(i*32), 0, 0, 208, 0, 32, 16, 1)
        
        pyxel.blt(L_salle-16, 0, 0, 240, 0, 16, 16, 1)#coin haut droit
        
        for j in range((H_salle-32)//32):#mur gauche
            pyxel.blt(0, 16+(j*32), 0, 192, 16, 16, 32, 1)
        
        pyxel.blt(0, H_salle-16, 0, 192, 48, 16, 16, 1)#coin bas gauche
        
        for k in range((L_salle-32)//32):#mur bas
            pyxel.blt(16+(k*32), H_salle-16, 0, 208, 48, 32, 16, 1)
        
        pyxel.blt(L_salle-16, H_salle-16, 0, 240, 48, 16, 16, 1)#coin bas droite
        
        for l in range((H_salle-32)//32):#mur droite
            pyxel.blt(L_salle-16, 16+(l*32), 0, 240, 16, 16, 32, 1)
            
        for n in range((L_salle-32)//32):
            for m in range((H_salle-32)//32):#terrain
                pyxel.blt(16+(n*32), 16+(m*32), 0, 208, 16, 32, 32)
        pyxel.blt(L_salle//2 -16, 48, 0, 192, 96, 32, 16, 1)
        pyxel.blt(L_salle//2 -16, 80, 0, 224, 64, 32, 16, 1)
        pyxel.blt(L_salle//2 -16, 124, 0, 192, 80, 32, 16, 1)
        self.dessiner_bouton_musique(L_salle - 36, H_salle - 36)

    def draw_transition(self):
        pyxel.cls(0)
        pyxel.text(L_salle // 2 - 20, H_salle // 2 - 10, f"Niveau {self.lvl_modif.lvl_actu}", pyxel.COLOR_WHITE)
        
    def draw_jeu(self):
        pyxel.cls(0)
        salle_actuelle = next(s for s in self.donjon.salles if s.x == self.joueur.grille_x and s.y == self.joueur.grille_y)
        
        if salle_actuelle.type == 0:
            salle_actuelle.salle_depart()
        elif salle_actuelle.type == 3:
            salle_actuelle.salle_boss()
        elif salle_actuelle.type == 2:
            salle_actuelle.salle_clee()
        elif salle_actuelle.type == 4:
            salle_actuelle.salle_fin()
        elif salle_actuelle.type == 5:
            salle_actuelle.salle_achat()
        else:
            salle_actuelle.salle_classique()
        #print(f"Ennemis dans cette salle: {[type(e) for e in salle_actuelle.ennemis]}")
        salle_actuelle.Ennemis_draw()
        salle_actuelle.Caisse_draw()
        self.joueur.dessiner()

        pyxel.blt(L_salle-32, 0, 0, 80, 160, 48, 8, 0)
        pyxel.text(L_salle-24, 2, str(self.joueur.rubis_recuperes), pyxel.COLOR_WHITE)

        if self.joueur.vie <= 0:
            pyxel.cls(0)
            pyxel.text(L_salle // 2 - 20, H_salle // 2 - 10, "GAME OVER", pyxel.COLOR_RED)
            pyxel.text(L_salle // 2 - 40, H_salle // 2 + 10, "R pour recommencer", pyxel.COLOR_RED)

    def draw_fin(self):
        pyxel.cls(0)
        pyxel.text(L_salle // 2 - 20, H_salle // 2 - 10, "The End", pyxel.COLOR_WHITE)
        pyxel.text(L_salle // 2 - 40, H_salle // 2 + 10, "R pour recommencer", pyxel.COLOR_WHITE)
    
    def niveau_suivant(self):
        vie_actuelle = self.joueur.vie + 1
        rubis_recuperes = self.joueur.rubis_recuperes + 3
        buff =self.joueur.buff
        self.lvl_modif = Lvl_modif(self.lvl_modif.lvl_actu + 1)
        self.donjon = Donjon(self.lvl_modif)
        self.donjon.verifier_porte_salle_depart()
        self.joueur = Joueur(self.donjon.salles[0].x, self.donjon.salles[0].y, self.donjon, buff)
        self.joueur.vie = vie_actuelle
        self.joueur.rubis_recuperes = rubis_recuperes
        self.musique.jouer_musique("jeu")
        self.etat = "transition"
        self.temps_transition = pyxel.frame_count

    def bouton_clique(self, x, y, w, h):
        return (x <= pyxel.mouse_x <= x + w and y <= pyxel.mouse_y <= y + h)

    def dessiner_bouton_musique(self, x, y):
        if self.musique.musique_active:
            pyxel.blt(x, y, 0, 224, 80, 16, 16, 1)
        else:
            pyxel.blt(x, y, 0, 240, 80, 16, 16, 1)

    def recommencer_jeu(self):
        self.niveau_actuel = 0
        self.lvl_modif = Lvl_modif(self.niveau_actuel)
        self.donjon = Donjon(self.lvl_modif)
        self.joueur = Joueur(self.donjon.salles[0].x, self.donjon.salles[0].y, self.donjon, {"degat": 0, "vitesse": 0, "cooldown": 0, "tir": 0})
        self.compteur_ennemis_abattus = 0
        self.etat = "menu"
        self.musique.jouer_musique("menu")

App()