import pyxel
import random
from time import sleep

# App parameters
SCREEN_WIDTH = 512
SCREEN_HEIGHT = 512
TITLE = "Tower Defense"
FPS = 30

# Tilemaps coordinates
# Hotbar
HOTBAR = (0,128,128,32)
# Towers
BASE = (0,32,32,32)
BASE_UPGRADE = (0,0,32,32)
BALLISTA = (0,96,32,32)
BALLISTA_UPGRADE = (0,64,32,32)
WATER_BALLISTA = (192,0,32,32)
WATER_BALLISTA_UPGRADE = (192,32,32,32)
STUN = (64,32,32,32)
STUN_UPGRADE = (64,0,32,32)
#Upgrade button
UPGRADE = (0,160,64,32)
# Enemies
BROWN_SHIP_1 = (96,96,32,32)
BROWN_SHIP_2 = (96,64,32,32)
BROWN_SHIP_3 = (64,384,32,32)
BROWN_SHIP_4 = (96,384,32,32)
PINK_SHIP_1 = (96,32,32,32)
PINK_SHIP_2 = (96,0,32,32)
PINK_SHIP_3 = (64,416,32,32)
PINK_SHIP_4 = (96,416,32,32)
BROWN_SHIP_1_PINK_SHIP_1 = (128,96,32,32)
BROWN_SHIP_2_PINK_SHIP_1 = (160,96,32,32)
BROWN_SHIP_3_PINK_SHIP_1 = (128,64,32,32)
BROWN_SHIP_2_PINK_SHIP_2 = (160,64,32,32)
BROWN_SHIP_1_PINK_SHIP_2 = (128,32,32,32)
BROWN_SHIP_1_PINK_SHIP_3 = (160,32,32,32)
BOSS_SHIP = (160,0,32,32)
EXPLOSION = (224,0,32,32)
SMALLER_EXPLOSION = (224,32,32,32)
WAVE = (320,0,128,32)
NUMBER_1 = (320,32,32,32)
NUMBER_2 = (352,32,32,32)
NUMBER_3 = (384,32,32,32)
NUMBER_4 = (416,32,32,32)
NUMBER_5 = (448,32,32,32)
NUMBER_6 = (480,32,32,32)
NUMBER_7 = (512,32,32,32)
NUMBER_8 = (544,32,32,32)
NUMBER_9 = (576,32,32,32)
NUMBER_0 = (608,32,32,32)
TRANSLATION_NUMBERS = {
    '1':NUMBER_1,
    '2':NUMBER_2,
    '3':NUMBER_3,
    '4':NUMBER_4,
    '5':NUMBER_5,
    '6':NUMBER_6,
    '7':NUMBER_7,
    '8':NUMBER_8,
    '9':NUMBER_9,
    '0':NUMBER_0
}

class tiles:
    def __init__(self) :
        self.x_tile = 0
        self.y_tile = 0
        self.size = 8
        self.rank = 0
        self.type = ''
        self.nb_entities = 0

class towers:
    def __init__(self):
        self.x_tower = 0
        self.y_tower = 0
        self.range = 0
        self.damage = 0
        self.speed = 0
        self.rotation = 0
        self.stun = 0
        towers.type = ''
        self.level = 1
    
    def check_if_shoot(self, actual_frame, enemies_list, tiles_matrix, app):
        if actual_frame == 0:
            return None
        elif actual_frame % self.speed == 0:
            self.find_enemy_to_shoot(enemies_list, tiles_matrix, app)
    
    def find_enemy_to_shoot(self, enemies_list, tiles_matrix, app):
        shootable_ennemies = []
        for enemy in enemies_list:
            distance_x = enemy.x_enemy - self.x_tower
            distance_y = enemy.y_enemy - self.y_tower
            if distance_x < 0:
                distance_x *= -1
            if distance_y < 0:
                distance_y *= -1
            if distance_x + distance_y <= self.range and enemy.type != 'ranker':
                shootable_ennemies.append(enemy)
        
        if len(shootable_ennemies) > 0:
            enemy_to_shoot = shootable_ennemies[0]
            for enemy in shootable_ennemies:
                if tiles_matrix[enemy.x_enemy][enemy.y_enemy].rank > tiles_matrix[enemy_to_shoot.x_enemy][enemy_to_shoot.y_enemy].rank:
                    enemy_to_shoot = enemy
            self.shoot(enemies_list, enemy_to_shoot, app)
        

    def shoot(self, enemies_list, enemy_to_shoot, app):
        # Rotation of the tower
        distance_x = enemy_to_shoot.x_enemy - self.x_tower
        distance_y = enemy_to_shoot.y_enemy - self.y_tower
        distance_x_temp = distance_x
        distance_y_temp = distance_y
        if distance_x_temp < 0:
            distance_x_temp *= -1
        if distance_y_temp < 0:
            distance_y_temp *= -1
        if distance_x_temp > distance_y_temp:
            if distance_x > 0:
                self.rotation = -90
            elif distance_x < 0:
                self.rotation = 90
        elif distance_x_temp < distance_y_temp:
            if distance_y > 0:
                self.rotation = 0
            elif distance_y < 0:
                self.rotation = 180

        # Hit animation
        app.enemies_recently_hit_list.append(enemy_to_shoot)

        if self.stun != 0:
            enemy_to_shoot.speed = 0
        enemy_to_shoot.life -= self.damage
        if enemy_to_shoot.life <= 0:
            enemies_list.remove(enemy_to_shoot)
            app.enemies_recently_dead_list.append(enemy_to_shoot)
            app.gold += enemy_to_shoot.value
            

class enemies:
    def __init__(self):
        self.x_enemy = 0
        self.y_enemy = 0
        self.life = 0
        self.speed = 0.0
        self.base_speed = 0.0
        self.stun_count = 0
        self.age = 0
        self.value = 0
        self.type = ''
        self.last_tile_visited = (0, 0)
    
    def __repr__(self):
        return 'x : ' + str(self.x_enemy) + ' y : ' + str(self.y_enemy)
    
    def check_if_move(self, actual_frame, tiles_matrix):
        if actual_frame == 0:
            return None
        if self.speed == 0:
            self.stun_count += 1
            if self.stun_count == FPS // 2:
                self.stun_count = 0
                self.speed = self.base_speed
        elif actual_frame % self.speed == 0:
            self.move_forward(tiles_matrix)

    def move_forward(self, tiles_matrix):
        for column in tiles_matrix:
            for tile in column:
                if (((tile.x_tile - self.x_enemy)**2 == 1 and tile.y_tile == self.y_enemy and tile.x_tile != self.last_tile_visited[0]) or ((tile.y_tile - self.y_enemy)**2 == 1 and tile.x_tile == self.x_enemy and tile.y_tile != self.last_tile_visited[1])) and tile.type == 'path':
                    self.last_tile_visited = (self.x_enemy, self.y_enemy)
                    self.x_enemy, self.y_enemy = tile.x_tile, tile.y_tile
                    
                    return None

class app:
    def __init__(self):
        pyxel.init(SCREEN_WIDTH, SCREEN_HEIGHT, TITLE, FPS)
        pyxel.load("theme.pyxres")
        self.game_over = False
        self.actual_frame = 0
        self.life = 100
        self.gold = 200000000000000000
        self.towers_list = []
        self.enemies_list = []
        self.enemies_recently_hit_list = []
        self.enemies_recently_dead_list = []
        self.enemies_to_come_list = []
        self.tiles_matrix = [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]]
        self.tile_creation()
        self.enemies_path()
        self.rank_path()
        self.menu = {'Type':"" , 'Damage':"" , 'Speed':"", 'Range':""}
        self.tower_menu = ()
        self.next_tower = ''
        self.wave = 0
        self.wait = 0
        self.speed_spawn = 60
        
        pyxel.run(self.update, self.draw)
    
    def tile_creation(self):
        tile_column = 0
        for i in range(0,511,32):
            tile_line = 0
            for j in range(0,511,32):
                tile = tiles()
                tile.x_tile = tile_column
                tile.y_tile = tile_line
                tile.rank = 0
                self.tiles_matrix[tile_column].append(tile)
                tile_line += 1
            tile_column+=1

    def enemies_path(self):
        for column in self.tiles_matrix:
            for tile in column :
                if (tile.y_tile in [1,3,5,7,9,11,13] and tile.x_tile not in [0,15]) or ((tile.y_tile in [4,8,12]) and tile.x_tile == 14) or ((tile.y_tile in [2,6,10]) and tile.x_tile == 1):
                    tile.type = 'path'
                if tile.y_tile == 14 and tile.x_tile == 1 :
                    tile.type = 'end'
                elif tile.y_tile == 0 and tile.x_tile == 14 :
                    tile.type = 'start'
    
    def rank_path(self):
        ranker = enemies()
        ranker.x_enemy = 14
        ranker.y_enemy = 0
        ranker.life = 0
        ranker.speed = pyxel.frame_count
        ranker.type = 'ranker'
        self.enemies_list.append(ranker)
        self.actual_rank = 0

    
    def spawn_enemies(self):
        if (len(self.enemies_list) == 0 or (len(self.enemies_list) == 1 and self.enemies_list[0].type == 'ranker')) and len(self.enemies_to_come_list) == 0:
            self.wait += 1
            if self.wait > FPS*2:
                self.wait = 0
                self.wave += 1

                # Adding the pink ships
                for i in range(self.wave*2):
                    pink = enemies()
                    pink.type = 'pink'
                    pink.x_enemy = 14
                    pink.y_enemy = 0
                    pink.life = 1 + self.wave//5
                    pink.speed = 10
                    pink.base_speed = 10
                    pink.value = 10 + self.wave//10
                    self.enemies_to_come_list.append(pink)
                
                # Adding the brown ships
                if self.wave > 20:
                    for i in range(self.wave):
                        brown = enemies()
                        brown.type = 'brown'
                        brown.x_enemy = 14
                        brown.y_enemy = 0
                        brown.life = 5 + self.wave//3
                        brown.speed = 7
                        brown.base_speed = 7
                        brown.value = 10 + self.wave//5
                        self.enemies_to_come_list.append(brown)
                
                random.shuffle(self.enemies_to_come_list)

                # Adding the boss ship
                if self.wave % 10 == 0:
                    boss = enemies()
                    boss.type = 'boss'
                    boss.x_enemy = 14
                    boss.y_enemy = 0
                    boss.life = 10 + self.wave*2
                    boss.speed = 30
                    boss.base_speed = 30
                    boss.value = 100 + self.wave*2
                    self.enemies_to_come_list.append(boss)

        if pyxel.frame_count % 30 == 0:
            for enemy in self.enemies_list:
                enemy.speed = enemy.base_speed
        if self.speed_spawn > 15 and (self.wave) % 10 == 0:
            self.speed_spawn = 60 - (self.wave//10*15)
        if pyxel.frame_count % self.speed_spawn == 0 and len(self.enemies_to_come_list) > 0:
            self.enemies_list.append(self.enemies_to_come_list[0])
            self.enemies_to_come_list.pop(0)
            print(self.speed_spawn)

    def check_for_game_over(self):
        if self.life <= 0 :
            self.game_over = True

    def closest_tile_to_mouse(self):
        position_x = pyxel.mouse_x
        position_y = pyxel.mouse_y
        closest_tile = tiles()
        closest_tile_distance = 10000000
        for column in self.tiles_matrix:
            for tile in column:
                center_x = tile.x_tile*32 + 16
                center_y = tile.y_tile*32 + 16
                distance_x = center_x - position_x
                distance_y = center_y - position_y
                if distance_x < 0:
                    distance_x *= -1
                if distance_y < 0:
                    distance_y *= -1
                total_distance = distance_x + distance_y
                if total_distance < closest_tile_distance and tile.type != 'path' and tile.type != 'start' and tile.type != 'end' and tile.y_tile < 14:
                    closest_tile = tile
                    closest_tile_distance = total_distance
        return closest_tile
    

    def drag_drop_towers(self):
        if pyxel.mouse_x <= 45 and pyxel.mouse_x  >= 12 and pyxel.mouse_y > 14*32 and pyxel.mouse_y  < 16*32 and pyxel.btnr(pyxel.MOUSE_BUTTON_LEFT):
            self.next_tower = 'base'
        elif pyxel.mouse_x <= 110 and pyxel.mouse_x  >= 75 and pyxel.mouse_y < 16*32 and pyxel.mouse_y  > 14*32 and pyxel.btnr(pyxel.MOUSE_BUTTON_LEFT):
            self.next_tower = 'ballista'
        elif pyxel.mouse_x <= 175 and pyxel.mouse_x  >= 140 and pyxel.mouse_y < 16*32 and pyxel.mouse_y  > 14*32 and pyxel.btnr(pyxel.MOUSE_BUTTON_LEFT):
            self.next_tower = 'water ballista'
        elif pyxel.mouse_x <= 240 and pyxel.mouse_x  >= 205 and pyxel.mouse_y > 14*32 and pyxel.mouse_y  < 16*32 and pyxel.btnr(pyxel.MOUSE_BUTTON_LEFT):
            self.next_tower = 'stun'

    def place_towers(self):
        if pyxel.mouse_y < 14*32:
            if pyxel.btnr(pyxel.MOUSE_BUTTON_LEFT) :
                closest_tile = self.closest_tile_to_mouse()
                    
                if self.next_tower == 'base' and self.gold >= 50:
                    tower = towers()
                    tower.x_tower = closest_tile.x_tile
                    tower.y_tower = closest_tile.y_tile
                    tower.range = 2
                    tower.speed = 5
                    tower.damage= 2
                    tower.rotation = 0
                    tower.type = 'base'
                    self.towers_list.append(tower)
                    self.gold -= 50
                
                if self.next_tower == 'ballista' and self.gold >= 250:
                    tower = towers()
                    tower.x_tower = closest_tile.x_tile
                    tower.y_tower = closest_tile.y_tile
                    tower.damage = 5
                    tower.range = 5
                    tower.speed = 20
                    tower.rotation = 0
                    tower.type = 'ballista'
                    self.towers_list.append(tower)
                    self.gold -= 250
                
                if self.next_tower == 'water ballista' and self.gold >= 250:
                    tower = towers()
                    tower.x_tower = closest_tile.x_tile
                    tower.y_tower = closest_tile.y_tile
                    tower.damage = 5
                    tower.range = 5
                    tower.speed = 20
                    tower.rotation = 0
                    tower.type = 'water ballista'
                    self.towers_list.append(tower)
                    self.gold -= 250
                    
                if self.next_tower == 'stun' and self.gold >= 100:
                    tower = towers()
                    tower.x_tower = closest_tile.x_tile
                    tower.y_tower = closest_tile.y_tile
                    tower.range = 3
                    tower.speed = 15
                    tower.damage=1
                    tower.stun = 1
                    tower.rotation = 0
                    tower.type = 'stun'
                    self.towers_list.append(tower)
                    self.gold -= 100

    def show_menu(self):
        if pyxel.mouse_y < 14*32:
            if pyxel.btnr(pyxel.MOUSE_BUTTON_RIGHT) :
                closest_tile = self.closest_tile_to_mouse()
                for tower in self.towers_list :
                    if tower.x_tower == closest_tile.x_tile and tower.y_tower == closest_tile.y_tile :
                        self.menu['Type'] = tower.type
                        self.menu['Damage'] = tower.damage
                        self.menu['Speed'] = tower.speed
                        self.menu['Range'] = tower.range
                        self.tower_menu = (tower.x_tower, tower.y_tower)
                        

    def upgrade(self):
        if pyxel.mouse_x > 11*32+10 and pyxel.mouse_x < 13*32+10 and pyxel.mouse_y > 15*32-10 and pyxel.mouse_y < 16*32-10 and pyxel.btnr(pyxel.MOUSE_BUTTON_LEFT):
            for tower in self.towers_list :
                if tower.x_tower == self.tower_menu[0] and tower.y_tower == self.tower_menu[1] and tower.level < 2:
                    self.gold -= 1000
                    tower.level += 1
                    if tower.type == 'base':
                        tower.damage = 5
                        tower.range = 5
                    
                    if tower.type == 'ballista' or tower.type == 'water ballista':
                        tower.damage = 10
                        tower.range = 10
                        tower.speed = 10
                    
                    if tower.type == 'stun':
                        tower.damage = 5
                        tower.range = 5
                        tower.speed = 5
                        
            
        

    def update(self):
        if not self.game_over:
            self.enemies_recently_hit_list = []
            self.spawn_enemies()
            self.drag_drop_towers()
            self.place_towers()
            for tower in self.towers_list:
                tower.check_if_shoot(self.actual_frame, self.enemies_list, self.tiles_matrix, self)
            for enemy in self.enemies_list:
                if enemy.x_enemy == 1 and enemy.y_enemy == 13 :
                    self.life -= enemy.life
                    self.enemies_list.remove(enemy)
                if enemy.type == 'ranker':
                    for column in self.tiles_matrix:
                        for tile in column:
                            if tile.x_tile == enemy.x_enemy and tile.y_tile == enemy.y_enemy:
                                tile.rank = self.actual_rank
                                self.actual_rank += 1
                enemy.check_if_move(self.actual_frame, self.tiles_matrix)    

            if self.actual_frame == FPS:
                self.actual_frame = 0
            else:
                self.actual_frame += 1

            self.show_menu()
            self.upgrade()

            self.check_for_game_over()
            print(pyxel.mouse_x)

    def draw(self) :
        pyxel.cls(0)
        if not self.game_over:
            for column in self.tiles_matrix:
                for tile in column:
                    if tile.type == 'path' :
                        pyxel.blt(tile.x_tile*32, tile.y_tile*32, 0, 32, 0,32,32)
                    elif tile.type == 'start' :         
                        pyxel.blt(tile.x_tile*32, tile.y_tile*32, 0, 32,0,32,32)
                    elif tile.type == 'end' :
                        pyxel.blt((tile.x_tile)*32, (tile.y_tile-1)*32,0,32,0,32,32)
                    else:
                        pyxel.blt(tile.x_tile*32, tile.y_tile*32,0,0,0,32,32)
                    

            for tower in self.towers_list:
                if tower.type == 'base':
                    if tower.level == 1:
                        pyxel.bltm(tower.x_tower*32,tower.y_tower*32,0,BASE[0],BASE[1],BASE[2],BASE[3],None,tower.rotation)
                    elif tower.level == 2:
                        pyxel.bltm(tower.x_tower*32,tower.y_tower*32,0,BASE_UPGRADE[0],BASE_UPGRADE[1],BASE_UPGRADE[2],BASE_UPGRADE[3],None,tower.rotation)
                elif tower.type == 'ballista':
                    if tower.level == 1:
                        pyxel.bltm(tower.x_tower*32,tower.y_tower*32,0,BALLISTA[0],BALLISTA[1],BALLISTA[2],BALLISTA[3],None,tower.rotation)
                    elif tower.level == 2:
                        pyxel.bltm(tower.x_tower*32,tower.y_tower*32,0,BALLISTA_UPGRADE[0],BALLISTA_UPGRADE[1],BALLISTA_UPGRADE[2],BALLISTA_UPGRADE[3],None,tower.rotation)
                elif tower.type == 'water ballista':
                    if tower.level == 1:
                        pyxel.bltm(tower.x_tower*32,tower.y_tower*32,0,WATER_BALLISTA[0],WATER_BALLISTA[1],WATER_BALLISTA[2],WATER_BALLISTA[3],None,tower.rotation)
                    if tower.level == 2:
                        pyxel.bltm(tower.x_tower*32,tower.y_tower*32,0,WATER_BALLISTA_UPGRADE[0],WATER_BALLISTA_UPGRADE[1],WATER_BALLISTA_UPGRADE[2],WATER_BALLISTA_UPGRADE[3],None,tower.rotation)
                elif tower.type == 'stun':
                    if tower.level == 1 :
                        pyxel.bltm(tower.x_tower*32,tower.y_tower*32,0,STUN[0],STUN[1],STUN[2],STUN[3],None,tower.rotation)
                    if tower.level == 2 :
                        pyxel.bltm(tower.x_tower*32,tower.y_tower*32,0,STUN_UPGRADE[0],STUN_UPGRADE[1],STUN_UPGRADE[2],STUN_UPGRADE[3],None,tower.rotation)

            for column in self.tiles_matrix:
                for tile in column:
                    tile.nb_entities = 0
                    enemies_types = {'brown':0, 'pink':0, 'boss':0}
                    for enemy in self.enemies_list:
                        if enemy.x_enemy == tile.x_tile and enemy.y_enemy == tile.y_tile :
                            tile.nb_entities += 1
                            if enemy.type != 'ranker':
                                enemies_types[enemy.type] += 1
                    
                    if enemies_types['boss'] > 0:
                        pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, BOSS_SHIP[0],BOSS_SHIP[1],BOSS_SHIP[2],BOSS_SHIP[3])
                    elif tile.nb_entities == 1 and enemies_types['pink'] == 1:
                        pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, PINK_SHIP_1[0],PINK_SHIP_1[1],PINK_SHIP_1[2],PINK_SHIP_1[3])
                    elif tile.nb_entities == 2 and enemies_types['pink'] == 2:
                        pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, PINK_SHIP_2[0],PINK_SHIP_2[1],PINK_SHIP_2[2],PINK_SHIP_2[3])
                    elif tile.nb_entities == 3 and enemies_types['pink'] == 3:
                        pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, PINK_SHIP_3[0],PINK_SHIP_3[1],PINK_SHIP_3[2],PINK_SHIP_3[3])
                    elif tile.nb_entities == 4 and enemies_types['pink'] == 4 :
                        pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, PINK_SHIP_4[0],PINK_SHIP_4[1],PINK_SHIP_4[2],PINK_SHIP_4[3])
                    elif tile.nb_entities == 1 and enemies_types['brown'] == 1 :
                        pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, BROWN_SHIP_1[0],BROWN_SHIP_1[1],BROWN_SHIP_1[2],BROWN_SHIP_1[3])
                    elif tile.nb_entities == 2 and enemies_types['brown'] == 2 :
                        pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, BROWN_SHIP_2[0],BROWN_SHIP_2[1],BROWN_SHIP_2[2],BROWN_SHIP_2[3])
                    elif tile.nb_entities == 3 and enemies_types['brown'] == 3 :
                        pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, BROWN_SHIP_3[0],BROWN_SHIP_3[1],BROWN_SHIP_3[2],BROWN_SHIP_3[3])
                    elif tile.nb_entities == 4 and enemies_types['brown'] == 4 :
                        pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, BROWN_SHIP_4[0],BROWN_SHIP_4[1],BROWN_SHIP_4[2],BROWN_SHIP_4[3])

                    elif tile.nb_entities == 2 and enemies_types['pink'] == 1 and enemies_types['brown'] == 1:
                        pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, BROWN_SHIP_1_PINK_SHIP_1[0],BROWN_SHIP_1_PINK_SHIP_1[1],BROWN_SHIP_1_PINK_SHIP_1[2],BROWN_SHIP_1_PINK_SHIP_1[3])
                    elif tile.nb_entities == 3 and enemies_types['pink'] == 2 and enemies_types['brown'] == 1:
                        pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, BROWN_SHIP_1_PINK_SHIP_2[0],BROWN_SHIP_1_PINK_SHIP_2[1],BROWN_SHIP_1_PINK_SHIP_2[2],BROWN_SHIP_1_PINK_SHIP_2[3])
                    elif tile.nb_entities == 3 and enemies_types['pink'] == 1 and enemies_types['brown'] == 2:
                        pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, BROWN_SHIP_2_PINK_SHIP_1[0],BROWN_SHIP_2_PINK_SHIP_1[1],BROWN_SHIP_2_PINK_SHIP_1[2],BROWN_SHIP_2_PINK_SHIP_1[3])
                    elif tile.nb_entities == 4 and enemies_types['pink'] == 2 and enemies_types['brown'] == 2:
                        pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, BROWN_SHIP_2_PINK_SHIP_2[0],BROWN_SHIP_2_PINK_SHIP_2[1],BROWN_SHIP_2_PINK_SHIP_2[2],BROWN_SHIP_2_PINK_SHIP_2[3])
                    elif tile.nb_entities == 4 and enemies_types['brown'] == 1 and enemies_types['pink'] == 3:
                        pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, BROWN_SHIP_1_PINK_SHIP_3[0],BROWN_SHIP_1_PINK_SHIP_3[1],BROWN_SHIP_1_PINK_SHIP_3[2],BROWN_SHIP_1_PINK_SHIP_3[3])
                    elif tile.nb_entities == 2 and enemies_types['brown'] == 3 and enemies_types['pink'] == 1 :
                        pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, BROWN_SHIP_3_PINK_SHIP_1[0],BROWN_SHIP_3_PINK_SHIP_1[1],BROWN_SHIP_3_PINK_SHIP_1[2],BROWN_SHIP_3_PINK_SHIP_1[3])

                    elif tile.nb_entities > 4 :
                        if enemies_types['pink'] == enemies_types['brown']:
                            pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, BROWN_SHIP_2_PINK_SHIP_2[0],BROWN_SHIP_2_PINK_SHIP_2[1],BROWN_SHIP_2_PINK_SHIP_2[2],BROWN_SHIP_2_PINK_SHIP_2[3])
                        if enemies_types['pink'] < enemies_types['brown']:
                            pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, BROWN_SHIP_4[0],BROWN_SHIP_4[1],BROWN_SHIP_4[2],BROWN_SHIP_4[3])
                        if enemies_types['pink'] > enemies_types['brown']:
                            pyxel.bltm(tile.x_tile*32, tile.y_tile*32, 0, PINK_SHIP_4[0],PINK_SHIP_4[1],PINK_SHIP_4[2],PINK_SHIP_4[3])

            for enemy in self.enemies_recently_hit_list:
                pyxel.bltm(enemy.x_enemy*32, enemy.y_enemy*32, 0, SMALLER_EXPLOSION[0],SMALLER_EXPLOSION[1],SMALLER_EXPLOSION[2],SMALLER_EXPLOSION[3])

            for enemy in self.enemies_recently_dead_list:
                enemy.age += 1
                if enemy.age < 10:
                    pyxel.bltm(enemy.x_enemy*32, enemy.y_enemy*32, 0, EXPLOSION[0],EXPLOSION[1],EXPLOSION[2],EXPLOSION[3])
            first_enemy_still_underaged = -1
            for i in range(len(self.enemies_recently_dead_list)):
                if self.enemies_recently_dead_list[i].age < 10:
                    first_enemy_still_underaged = i
                    break
            if first_enemy_still_underaged != -1:
                for j in range(first_enemy_still_underaged):
                    self.enemies_recently_dead_list.pop(j)

            # Afficher la vague au début
            if self.wait != 0:
                pyxel.bltm(6*32,5*32,0,WAVE[0],WAVE[1],WAVE[2],WAVE[3])
                str_wave = str(self.wave + 1)
                list_numbers_to_show = []
                if len(str_wave) % 2 != 0:
                    list_numbers_to_show.append(NUMBER_0)
                for i in range(len(str_wave)):
                    list_numbers_to_show.append(TRANSLATION_NUMBERS[str_wave[i]])
                nb_nb = len(list_numbers_to_show)
                
                for i in range(nb_nb):
                        pyxel.bltm((8 - nb_nb + i + nb_nb//2)*32,7*32,0,list_numbers_to_show[i][0],list_numbers_to_show[i][1],list_numbers_to_show[i][2],list_numbers_to_show[i][3])

            pyxel.bltm(64, 14.5*32, 0, HOTBAR[0], HOTBAR[1], HOTBAR[2], HOTBAR[3], colkey=None, rotate=0, scale=2)
            pyxel.blt(8*32,14*32, 1, 0,0, 256, 2*32)
            pyxel.text(9*32, 14*32+12, "Type : "+self.menu['Type'],1)
            pyxel.text(9*32, 14*32+24, "Damage : "+str(self.menu['Damage']),1)
            pyxel.text(9*32, 14*32+36, "Speed : "+str(self.menu['Speed']),1)
            pyxel.text(9*32, 14*32+48, "Range : "+str(self.menu['Range']),1)
            if self.menu['Type'] != '' :
                pyxel.bltm(11*32+10, 15*32-10, 0, UPGRADE[0], UPGRADE[1], UPGRADE[2], UPGRADE[3])

            pyxel.text(14*32,14*32+12,"Lives : "+ str(self.life),1) 
            pyxel.text(14*32,14*32+24, "Gold : "+ str(self.gold), 1)
            pyxel.text(14*32,14*32+36, "Wave : "+ str(self.wave), 1)
        else:
            pyxel.text(64,64,'Game Over', 2)
        pyxel.rect(pyxel.mouse_x, pyxel.mouse_y,7,7,1)


app()