# Modification du code pour ajouter un point rouge comme point initial et ajuster la taille des planètes proportionnellement à leur masse.

import pygame
import math
import random

# Initialisation de Pygame
pygame.init()
font = pygame.font.SysFont(None, 32)

# Constantes
LARGEUR, HAUTEUR = 1000, 800
G = 66.7  # Constante gravitationnelle adaptée à l’échelle du jeu
BLANC = (255, 255, 255)
NOIR = (0, 0, 0)
PLANETE_COULEUR = (100, 100, 255)
SONDE_COULEUR = (255, 50, 50)
POINT_DEPART_COULEUR = (255, 0, 0)  # Couleur rouge pour le point de départ
VITESSE_SONDE = 100.0  # Vitesse unique de la sonde
FPS = 60

# Fenêtre
fenetre = pygame.display.set_mode((LARGEUR, HAUTEUR))
pygame.display.set_caption("Champ Gravitationnel")

# Classe pour les planètes
class Planete:
    def __init__(self, x, y, masse):
        self.x = x
        self.y = y
        self.masse = masse
        # Rayon proportionnel à la masse
        self.rayon = int(masse / 200) # Ajustement pour que le rayon soit visible

    def dessiner(self, surface):
        pygame.draw.circle(surface, PLANETE_COULEUR, (int(self.x), int(self.y)), self.rayon)

# Classe pour la sonde
class Sonde:
    def __init__(self, x, y, vx, vy):
        self.x = x
        self.y = y
        self.vx = vx
        self.vy = vy
        self.trajectoire = []

    def update(self, dt, planetes):
        ax, ay = 0, 0
        for p in planetes:
            dx = self.x - p.x
            dy = self.y - p.y
            r = math.hypot(dx, dy)
            if r == 0:
                continue
            ax += - G * p.masse * dx  / r**3
            ay += - G * p.masse * dy  / r**3
        self.vx += ax * dt
        self.vy += ay * dt
        self.x += self.vx * dt
        self.y += self.vy * dt
        self.trajectoire.append((self.x, self.y))

    def dessiner(self, surface):
        if len(self.trajectoire) > 1:
            pygame.draw.lines(surface, NOIR, False, self.trajectoire, 1)
        pygame.draw.circle(surface, SONDE_COULEUR, (int(self.x), int(self.y)), 4)

# classe pour la cible
class Cible:
    def __init__(self, x, y, rayon=10):
        self.x = x
        self.y = y
        self.rayon = rayon

    def dessiner(self, surface):
        pygame.draw.circle(surface, (0, 200, 0), (int(self.x), int(self.y)), self.rayon)
        pygame.draw.circle(surface, (0, 100, 0), (int(self.x), int(self.y)), self.rayon, 2)

    def est_touchee(self, x, y):
        dx = x - self.x
        dy = y - self.y
        return dx * dx + dy * dy <= self.rayon ** 2

# Fonction pour générer une nouvelle planète
def est_trop_proche(x, y, planetes, distance_min):
    for p in planetes:
        dx = p.x - x
        dy = p.y - y
        distance = math.hypot(dx, dy)
        if distance < distance_min:
            return True
    return False

def generer_nouvelle_planete(planetes):
    distance_min = 100  # Distance minimale entre les planètes
    while True:
        masse = random.uniform(1000, 10000)
        x = random.randint(100, LARGEUR - 100)
        y = random.randint(100, HAUTEUR - 100)
        if not est_trop_proche(x, y, planetes, distance_min):
            break
    return Planete(x, y, masse)

# Création des planètes initiales
planetes = [
    Planete(400, 400, masse=1000),
    Planete(700, 600, masse=10000)
]

cible = Cible(900, 200)

# Lancement du jeu
clock = pygame.time.Clock()
sonde = None
point_depart = (100, 100)  # Coordonnées du point de départ
en_cours = True
ligne_visible = True
mx_ligne, my_ligne = None, None
angle_ligne = None

RECT_START = pygame.Rect(30, HAUTEUR - 60, 100, 30)
RECT_STOP = pygame.Rect(150, HAUTEUR - 60, 100, 30)
simulation_active = True

message = ""
message_timer = 0

while en_cours:
    dt = clock.tick(FPS) / 1000

    if message and pygame.time.get_ticks() - message_timer > 2000:  # 2s
        message = ""

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            en_cours = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            mx, my = pygame.mouse.get_pos()
            
            # Bouton "Lancer"
            if RECT_START.collidepoint(mx, my):
                simulation_active = True

            # Bouton "Stop"
            elif RECT_STOP.collidepoint(mx, my):
                simulation_active = False

            # Lancer sonde uniquement si clic ailleurs que sur les boutons
            elif not RECT_START.collidepoint(mx, my) and not RECT_STOP.collidepoint(mx, my):
                angle = math.atan2(my - point_depart[1], mx - point_depart[0])
                vx = VITESSE_SONDE * math.cos(angle)
                vy = VITESSE_SONDE * math.sin(angle)
                sonde = Sonde(point_depart[0], point_depart[1], vx, vy)
                ligne_visible = True
                mx_ligne, my_ligne = mx, my
                angle_ligne = math.degrees(angle)
            

        elif event.type == pygame.USEREVENT:
            pygame.time.set_timer(pygame.USEREVENT, 0)

    # MAJ
    if sonde:
        sonde.update(dt, planetes)

    if sonde and cible.est_touchee(sonde.x, sonde.y):
        message = "🎯 Cible atteinte ! Niveau +1"
        message_timer = pygame.time.get_ticks()
        sonde = None

        # Nouvelle planète aléatoire
        planetes.append(generer_nouvelle_planete(planetes))

        # Nouvelle cible
        cible.x = random.randint(100, LARGEUR - 100)
        cible.y = random.randint(100, HAUTEUR - 100)

        # Réinitialise la sonde après un court délai
        pygame.time.set_timer(pygame.USEREVENT, 2000)

    # Affichage
    fenetre.fill(BLANC)
    for p in planetes:
        p.dessiner(fenetre)
        
    # Boutons
    pygame.draw.rect(fenetre, (0, 200, 0), RECT_START)
    pygame.draw.rect(fenetre, (200, 0, 0), RECT_STOP)
    fenetre.blit(font.render("Lancer", True, BLANC), (RECT_START.x + 10, RECT_START.y + 5))
    fenetre.blit(font.render("Stop", True, BLANC), (RECT_STOP.x + 20, RECT_STOP.y + 5))    
    
    if sonde and simulation_active:
        sonde.dessiner(fenetre)
    cible.dessiner(fenetre)
    pygame.draw.circle(fenetre, POINT_DEPART_COULEUR, point_depart, 5)  # Dessiner le point de départ

    if message:
        texte = font.render(message, True, (255, 0, 0))
        fenetre.blit(texte, (LARGEUR // 2 - texte.get_width() // 2, 50))

    
    # Ligne de visée persistante (rouge) et angle
    if ligne_visible and mx_ligne is not None:
        pygame.draw.line(fenetre, (255, 0, 0), point_depart, (mx_ligne, my_ligne), 2)
        texte_angle = font.render(f"Angle: {angle_ligne:.1f}°", True, (200, 0, 0))
        fenetre.blit(texte_angle, (300, HAUTEUR - 60))

    pygame.display.flip()

pygame.quit()

