##README
##
## comportement de deplacement "direct":
##      l'acceleration pointe vers l'objectif
##      on decelere seulement l'objectif passe
##
## conduit a un oscillateur
##
## controle:
## il est possible de changer l'objectif en cliquant sur l'ecran




#objectif a atteindre
class Objectif():
    
    def __init__(self,x,y):
        self.x=x
        self.y=y


#agent avec un objectif
class Agent():

    
    
    def __init__(self,dx,dy,obj):
        self.objectif=obj
        self.x=dx
        self.y=dy

        #par defaut pas de dynamique
        self.vx=20
        self.vy=0
        self.ax=0
        self.ay=0
        self.dt=0.1
        
        #acceleration maximale
        self.aMax=10

        #trajectoire
        self.traj=[[self.x,self.y]]
        

    def evoluer(self):
        self.vx=self.vx+self.ax*self.dt
        self.vy=self.vy+self.ay*self.dt
        self.x=self.x+self.vx*self.dt
        self.y=self.y+self.vy*self.dt

        #met a jour trajectorie faite
        self.traj+=[[self.x,self.y]]        


    def afficher(self):
        print("(x,y): "+str(self.x)+","+str(self.y)+"  vx,vy: "+str(self.vx)+","+str(self.vy))


    #met a jour son acceleration en fonction objectif
    def calculerObj(self):
        distance=self.distance(self.objectif)
        self.ax=self.aMax*(self.objectif.x-self.x)/distance
        self.ay=self.aMax*(self.objectif.y-self.y)/distance

    def distance(self,O):
        dx=(O.x-self.x)
        dy=(O.y-self.y)
        d2=dx*dx+dy*dy
        from math import sqrt
        return sqrt(d2)


# systeme c'est un agent et un objectif
class Systeme():

    #initialise le systeme avec les coordonnees de l'agent
    def __init__(self,x,y):
        self.objectif=Objectif(200,200)
        self.agent=Agent(x,y,self.objectif)

    #evoluer le jeu
    def evoluer(self):
        self.agent.calculerObj()
        self.agent.evoluer()
        
    #dessin des agents
    def dessiner(self):
        WHITE = (0xFF, 0xFF, 0xFF)
        RED = (0xFF, 0x00, 0x00)
        BLUE = (0x00, 0xFF, 0x00)
        BLACK = (0x00, 0x00, 0x00)
        screen.fill(WHITE)

        pygame.draw.ellipse(screen,RED,(jeu.agent.x-5,jeu.agent.y-5,10,10))
        pygame.draw.ellipse(screen,BLUE,(jeu.objectif.x-5,jeu.objectif.y-5,10,10))

        #dessiner trajectoire
        for x in range(len(self.agent.traj)-1):
            pygame.draw.line(screen,BLACK,self.agent.traj[x],self.agent.traj[x+1],1)


import pygame
pygame.init()
size = (700, 500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Moteur")


#boucle
done = False
jeu=Systeme(100,50)

# horloge
clock = pygame.time.Clock()
# -------- boucle de jeu
while not done:
    # --- gestion des evenements
    for event in pygame.event.get():

        #joueur quitte
        if event.type == pygame.QUIT: 
            done = True

        #si on appui souris: change objectif
        if event.type == pygame.MOUSEBUTTONDOWN:
            jeu.objectif.x=pygame.mouse.get_pos()[0]
            jeu.objectif.y=pygame.mouse.get_pos()[1]
            

            
    # --- evolution
    jeu.evoluer()
    
    # --- dessin
    jeu.dessiner()
        
    # --- mise a jour graphique
    pygame.display.flip()
    # --- attente
    clock.tick(60)

pygame.quit()
   

