problème java.awt.Robot

perluce
problème java.awt.Robot

Bonjour,

j'utilise la classe Robot pour me déplacer automatiquement sur le panel. Mais j'aimerais qu'au clic de l'utilisateur, un point soit créé.

J'ai un thread qui exécute le code du robot. Et j'appelle ce thread dans mon MouseClicked, juste avant que l'utilisateur puisse cliquer pour sélectionner son point. Seulement, le clic, ne fait rien, le robot continue à se déplacer automatiquement. Est ce que quelqu'un saurait comment je peux régler ce problème?

Voici mon code:

thread implémentant le robot

import java.awt.Robot;

public class FirstThread extends Thread {

	PanelParallèle p;
	boolean actif;
	 
    
    public FirstThread(PanelParallèle p) {
       this.p =p;
       this.actif=false;
       
    }

    public void run() {
    	actif=true;
    	
    	while(actif==true){
        	
    		try{
      			Robot r= new Robot();
      			for (int i = 0; i < 300; i++)
      	        {
      	           for (int j = 0; j < 300; j++)
      	           {
      	              if ((j - (p.coefDir2 * i) - (p.absOr2 * 20)) < 0.5f && (j - (p.coefDir2 * i) - (p.absOr2 * 20)) > -0.5f)
      	              r.mouseMove((int)(i+p.getLocationOnScreen().getX()),(int)(j+p.getLocationOnScreen().getY()));
      	           }
      	        }
      			//Thread.yield();
      		}
      		 catch(Exception ex){
      			 System.out.println("Exception :"+ex.getMessage());
      		 }
      		    }
    }
   
    public void setActif(boolean a){
    	actif=a; 	
    }
}

méthode mouseClicked qui exécute le thread

   public void mouseClicked(MouseEvent e)

   {
	Graphics g = getGraphics();
 if(etape==5){
    	  System.out.println("dans 6ème étape");
		  thr1 = new FirstThread(this);	
		  //SwingUtilities.invokeLater(thr1);
		  thr1.start(); 
		  System.out.println("fin thread");
      }
      
      if(etape==6){
    	  System.out.println("dernière étape");
  			thr1.setActif(false);
  			System.out.println(thr1.actif);
  			thr1=null;
  		
  			p4 = new MonPoint(e.getX(),e.getY());
  			   	  
  			System.out.println("p4 x" +p4.x);
  			System.out.println("p4 y" +p4.y);
  			   		p4.affiche(g);
  			   		li.add(p4);
  			   		forme.add(p4);
  			   	
  			   		Ligne l2 = new Ligne(li.size());
  			   		MonPoint[] tab = new MonPoint[li.size()];

  			   		for (int k=0; k<li.size(); k++){
  			   		tab[k]=li.get(k);
  			   		l2.points=tab;
  			   		}
  			   		l2.affiche(g);
  			   		forme.add(l2);	
  			}
      etape++;
	 }
perluce

Bonjour,

je reviens sur mon problème avec la classe java.awt.Robot. Etant donné que je n'ai eu aucune réponse, je met tout mon code en espérant que quelqu'un pourra trouver ce qui ne va pas parce que ça fait plus d'une semaine que je n'y arrive pas.

Classe du thread


import java.awt.Robot;

/**
 * thread pour la construction d'une parallèle
 * @author au
 *
 */
 public class FirstThread extends Thread {

	PanelParallèle p;
	boolean actif;
	 
    
	 public FirstThread(PanelParallèle p) {
       this.p =p;
       this.actif=false;
       
    }
    
	 public void run() {
    	actif=true;
    
    	while(actif==true){
    		try{
      			Robot r= new Robot();
      			for (int i = 0; i < 300; i++)
      	        {
      	           for (int j = 0; j < 300; j++)
      	           {
      	              if ((j - (p.coefDir2 * i) - (p.absOr2)) < 0.5f && (j - (p.coefDir2 * i) - (p.absOr2)) > -0.5f){
      	              r.mouseMove((int)(i+p.getLocationOnScreen().getX()),(int)(j+p.getLocationOnScreen().getY()));}
      	           }
      	        }
      		}
      		 catch(Exception ex){
      			 System.out.println("Exception :"+ex.getMessage());
      		 }
      		    }  	
    }
   
    public void setActif(boolean a){
    	actif=a; 	
    }
}

Classe qui définit un point



import java.awt.*;


/**
 * Classe définissant un point et les opérations effectuées sur un point
 * 
 */

public class MonPoint extends Geometrie {

/**
 * 
*/
	private static final long serialVersionUID = 1L;

/**
 * <p>Abscisse du point</p>
 * 
 */
   public int x;

/**
 * <p>Ordonnée du point</p>
 * 
 */
    public int y;

    /**
     * Construit et initialise un point aux coordonnées a, o
     * @param a abscisse du point
     * @param o ordonnée du point
     */
    public MonPoint(int a, int o){
    	this.x=a;
    	this.y=o;
    }
   
/**
 * Définit l'abscisse d'un point
 * @param a abscisse du point
 */
    public void setX(int a) {        
       this.x=a;
    } 

/**
 * Définit l'ordonnée d'un point
 * @param o ordonnée du point
 */
    public void setY(int o) {        
       this.y=o;
    } 

/**
 * Retourne l'abscisse du point
 * @return abscisse du point
 */
    public int getX() {        
        // your code here
        return this.x;
    } 

/**
 *Retourne l'ordonnée du point
 * @return ordonnée du point
 */
    public int getY() {        
        // your code here
        return this.y;
    } 

/**
 * Calcule la distance entre le point et un autre point
 * 
 * @return distance entre les deux points
 */
    public int distance(MonPoint p) {
        int dx = p.x - x ;
        int dy = p.y - y ;
        int res= dx*dx + dy*dy;
        return res ;         
    } 
  
/**
 * effectue la rotation d'un point
 * @param a angle de rotation
 */

   public void rotation (double a)
   {             
   }

	public void affiche(Graphics g) {
		// TODO Auto-generated method stub
		
		Graphics2D g2 = (Graphics2D) g;
		 if (selected)
	         g2.setColor(Color.blue);
	      else
	         g2.setColor(Color.black);
		
        g2.drawRect(x,y,1,1);
        
      
	}

	public boolean contains(int x, int y) {
		
		return ((this.x==x) && (this.y==y));
	
	}
	public int nbPoints() {
		return 1;
	}

	@Override
	public String typeGeom() {
		return "point";
	}	
 }

Classe qui définit une ligne



import java.awt.*;


/**
 * 
 * 
 */
public class Ligne extends Geometrie {


/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
/**
 * <p>Tableau représentant tous les points de la ligne</p>
 * 
 */
   public MonPoint[] points;
   int size;

  /**
   * 
   *
   */ 
  public Ligne(){
	  this.points=null;
	  this.size=0;
  }
  /**
   * construit une ligne vide de taille s
   * @param s
   */
  public Ligne(int s){
	  this.points=null;
	  this.size=s;
  }
  /**
   * construit une ligne et l'initialise avec les points contenus dans p
   * @param p tableau contenant les points de la ligne
   */
  public Ligne(MonPoint p[]){
	  this.points=p;
	  this.size=p.length;
  }
  
/**
 * initialise les points de la ligne
 * 
 */
    public void setPoints(MonPoint p[]) { 
    	this.points=p;
          } 

/**
 * retourne les points de la ligne
 * 
 * @return points constituant la ligne
 */
    public MonPoint[] getPoints() {        
        // your code here
        return points;
    } 

/**
 * renvoie le nombre de points de la ligne
 * 
 * @return nombre de points de la ligne
 */
    public int nbPoints() {        
        // your code here
        return this.points.length;
    } 

/**
 * retourne le premier point de la ligne
 * 
 * @return premier point de la ligne
 */
    public MonPoint getPointDeb() {        
       
        return this.points[0];
    } 

/**
 * initilaise le point de début de la ligne à p
 * @param p point de début
 */
    public void setPointDeb(MonPoint p){
    	this.points[0]=p;
    }
 
    
/**
 * retourne le dernier point de la ligne
 * 
 * @return dernier point de la ligne
 */
    public MonPoint getPointFin() {        
        
        	return this.points[nbPoints()-1];
    } 
    
/**
 * initilaise le point de fin de la ligne à p
 * @param p point de fin 
 */
    public void setPointFin(MonPoint p){
    	this.points[nbPoints()-1]= p;
    }

    
     
  
  /**
   * donne l'image de la ligne par rapport au point o avec un angle a
   * @param o point de référence pour la rotation
   * @param a angle de rotation
   */
    public void rotation(double a) {        
        // your code here    
    }


public void affiche(Graphics g) {
	// TODO Auto-generated method stub

	Graphics2D g2 = (Graphics2D) g;
	
	 int[] abscisse = new int[this.points.length];
	    int[] ordonnee = new int[this.points.length];
	    // stock abscisses et ordonnées des sommets du polygone dans un tableau.
	    for (int i=0 ; i < this.points.length ; i++) {
	      abscisse[i] = this.points[i].getX();
	      ordonnee[i] = this.points[i].getY();
	    }
	
	    if (selected)
	         g2.setColor(Color.blue);
	      else
	         g2.setColor(Color.black);
	    
	    for (int i=0; i<this.points.length-1; i++){
		 	this.points[i].affiche(g2);
	 }  
	  g2.drawPolyline(abscisse,ordonnee,abscisse.length);
	  
}


public boolean contains(int x, int y) {
		
boolean verif = false;

	return verif;
}

public String typeGeom() {
	// TODO Auto-generated method stub
	return "ligne";
}
	
}

Classe geometrie


import java.awt.Graphics;
import java.io.Serializable;

public abstract class Geometrie implements Serializable{

  public boolean selected = false;
  
    public abstract void affiche(Graphics g) ;
       	
    public abstract void rotation(double a);
    
    public abstract boolean contains (int x, int y);
    
      public abstract int nbPoints();
 
 	public abstract  String typeGeom();
}

Classe qui permet de dessiner

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;


public class Parallèle extends JFrame 
{
  
	private static final long serialVersionUID = 1L;
PanelParallèle panel = new PanelParallèle();
 
  
   public static void main (String[] args)
   {
	   Parallèle para = new Parallèle();
	   para.setVisible(true);
   }
   
   public Parallèle()
   {
      Dimension taille_ecran = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
      int hauteur_ecran = (int)taille_ecran.getHeight();
      int largeur_ecran = (int)taille_ecran.getWidth();
      
      setTitle("Parallèle");
      setLocation((largeur_ecran / 2) - (175), (hauteur_ecran / 2) - (200));
      setSize(350, 400);
      
      setLayout(null);
      
      panel.setBounds(20, 20, 300, 300);    
      add(panel);
      panel.setBackground(Color.white);
     
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      
      this.setVisible(true);
         
   } 
}

class PanelParallèle extends JPanel implements MouseListener
{
	private static final long serialVersionUID = 1L;
   MonPoint p1, p2,p3,p4,p5;
   float coefDir1 = 0f;
   float absOr1 = 0f;
   
  public  float coefDir2 = 0f;
  public float absOr2 = 0f;
 
   String eqDroite1 = "";
   String eqDroite2 = "";
   
   int etape = 0;
   int x,y;
   String message = "";
   Parallèle par;
 
   ArrayList <Geometrie> forme = new ArrayList <Geometrie>();
   ArrayList <MonPoint> li2 = new ArrayList <MonPoint>();
   ArrayList <MonPoint> li = new ArrayList <MonPoint>();
   
   FirstThread  thr1;

   public PanelParallèle()
   {
	  setBackground(Color.white);
      addMouseListener(this);   
    
   }
   
   public void paintComponent(Graphics g)
		   {
		      super.paintComponent(g);
		      
	
		      for (int i = 0; i < forme.size(); i++)
		      {
		         if (forme.get(i) instanceof Geometrie)
		         {
		        	 Geometrie geom= (Geometrie) forme.get(i);
		            geom.affiche(g);
		         }
		      }
		      g.setColor(new Color(0, 0, 0));
				}	
   
   
   public String CalculEqDroite1(MonPoint p, MonPoint pp)
   {
      System.out.println("1er point :" +p.x+ " "+p.y);
      System.out.println("2ème point :" +pp.x+ " "+pp.y);
      
      coefDir1 = (float) ((float) (pp.y - p.y)) / ((float) (pp.x - p.x));
      absOr1 =  (float) (p.y - (p.x * coefDir1)) ;
      return ("y = " + coefDir1 + "x + " + absOr1);
   }
   
   public String CalculEqDroite2()
   {
      coefDir2 = coefDir1;
      absOr2 =  (float) (p3.y - (p3.x * coefDir2));
      return ("y = " + coefDir2 + "x + " + absOr2);
   }
   
    public  void mouseClicked(MouseEvent e)

   {
	Graphics g = getGraphics();
	
	 
		System.out.println("dans cas 1");   
      if (etape == 0)
      {
    	  System.out.println("dans 1ère étape");
         p1= new MonPoint(e.getX(),e.getY());
	p1.affiche(g);
	li2.add(p1);
	forme.add(p1);

      }
      
      if (etape == 1)
      {
    	System.out.println("dans 2ème étape");
        p2 = new MonPoint( e.getX(),e.getY());
        p2.affiche(g);
        li2.add(p2);
        forme.add(p2);
      }
      
      if (etape == 2)
      {
    	  System.out.println("dans 3ème étape");
    		Ligne l1 = new Ligne(li2.size());
			MonPoint[] tab = new MonPoint[li2.size()];
			
			for (int i=0; i<li2.size(); i++){
				tab[i]=li2.get(i);
				l1.points=tab;
			}
    	  
	l1.affiche(g);
	forme.add(l1);
         eqDroite1 = CalculEqDroite1(p1,p2);
         System.out.println(coefDir1);
      }
      
      if (etape == 3)
      {
    	  System.out.println("dans 4ème étape");
    	 
         p3 = new MonPoint( e.getX(),e.getY());
	 p3.affiche(g);
	 li.add(p3);
         forme.add(p3);
      }
      
      if (etape == 4)
      {
    	 System.out.println("dans 5ème étape");
         eqDroite2 = CalculEqDroite2();
         System.out.println(eqDroite2);
         System.out.println(coefDir2);
         System.out.println(absOr2);
      }
      if(etape==5){
    	  System.out.println("dans 6ème étape");
    	  
		  thr1 = new FirstThread(this);	
		  thr1.start(); 
		 
		   thr1.setPriority(Thread.MIN_PRIORITY);
		 // System.out.println("fin thread");	   	
      }
      
     if(etape==6){
    	  System.out.println("dernière étape");
    
    	  thr1.setActif(false);
			System.out.println(thr1.actif);
			thr1=null;
			System.gc();
    
    			p4 = new MonPoint(e.getX(),e.getY());
    			   	  
    			System.out.println("p4 x" +p4.x);
    			System.out.println("p4 y" +p4.y);
    			p4.affiche(g);
    			li.add(p4);
    			forme.add(p4);
    			Ligne l2 = new Ligne(li.size());
    			MonPoint[] tab = new MonPoint[li.size()];
    			
    			   	for (int k=0; k<li.size(); k++){
    			   		tab[k]=li.get(k);
    			   		l2.points=tab;
    			   		}
    			   	l2.affiche(g);
    			    forme.add(l2);	
  			
     }
      etape++;

      this.repaint();
   }
   
   public void mousePressed(MouseEvent e)
   {
   
   }
   
   public void mouseReleased(MouseEvent e)
   {
   
   }
   
   public void mouseExited(MouseEvent e)
   {
   
   }
   
   public void mouseEntered(MouseEvent e)
   {
   
   }
}

Alors, les classes Ligne, MonPoint et Geometrie ne présentent aucun problème. Je oense que le problème doit se situer au niveau du code de mon thread ou dans la méthode mouseClicked() lorsque j'appelle le thread.

Le problème qui se pose est en fait qu'au clic après etape==5, je dois pouvoir créer mon point et arrêter le thread. Mais je n'y arrive pas, c'est après plusieurs tentatives de clics que j'arrive à créer le point et de ce fait, il n'est pas créé à l'endroit voulu parce que je ne sais pas exactement quand le clic est pris en compte.

J'explique vite fiat, une fois qu'on exécute Parallèle, il suffit juste de cliquer à chaque fois sur le panel, et à chaque clic, on passe à l'étape suivante.

Si jamais quelqu'un arrive à voir à quoi est dû mon problème, ça m'aiderait beaucoup.

Merci d'avance pour l'aide.

perluce

Niroken

Bonjour Perluce

J'ai regardé ton code de façcon assez brève, je l'avoue
et je ne peux faire qu'une supposiiton sur ce qui ne va pas
à savoir le "Graphics g = getGraphics()" sur lequel tu bases
ton paint après.

Bon ceci j'ai repris une des petites applis que j'avais codé et
j'espère que tu y trouveras ce que tu veux...
Quand le curseur se met a bouger tt seul tu cliques et des points
apparaissent...

Cette appli est proche de celle dont tu as fait voir le code donc
ca devrait être ressemblant :

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class FenetreMath extends JFrame implements ActionListener
{
	PanelMath panelMath = new PanelMath();
	JButton jButton1 = new JButton();
	JButton jButton2 = new JButton();
	JLabel jLabel1 = new JLabel("Echelle : 1 unité <-> 20 px"); 
	
	public static void main (String[] args)
	{
		FenetreMath fenetreMath = new FenetreMath();
	}
	
	public FenetreMath()
	{
		Dimension taille_ecran = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
		int hauteur_ecran = (int)taille_ecran.getHeight();
		int largeur_ecran = (int)taille_ecran.getWidth();
		
		setTitle("Un peu de math ...");
		setLocation((largeur_ecran / 2) - (175), (hauteur_ecran / 2) - (200));
		setSize(350, 400);
		
		setLayout(null);
		
		panelMath.setBounds(20, 20, 300, 300);
				
		jLabel1.setBounds(20, 330, 200, 20);
				
		add(panelMath);
		add(jLabel1);
				
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
		
		//JOptionPane.showMessageDialog(null, "Cliquez pour placer le premier point");
	}
	
	public void actionPerformed(ActionEvent e)
	{
	
	}
}

class PanelMath extends JPanel implements MouseListener
{
	int coordXPoint1 = 0;
	int coordYPoint1 = 0;
	
	int coordXPoint2 = 0;
	int coordYPoint2 = 0;
	
	int coordXPoint3 = 0;
	int coordYPoint3 = 0;
	
	float coefDir1 = 0f;
	float absOr1 = 0f;
	
	float coefDir2 = 0f;
	float absOr2 = 0f;
	
	String eqDroite1 = "";
	String eqDroite2 = "";
	
	int pointToDrawX = 0;
	int pointToDrawY = 0;
	
	int etape = 0;
	
	public PanelMath()
	{
		addMouseListener(this);
	}
	
	public void paint(Graphics g) 
	{
        if (etape == 0)
		{
			g.setColor(new Color(255, 255, 255));
			g.fillRect(0, 0, 300, 300);
			
			g.setColor(new Color(0, 0, 0));
			g.drawRect(0, 0, 299, 299);
			g.drawLine(20, 150, 280, 150);
			g.drawLine(150, 20, 150, 280);
			
			g.drawLine(275, 145, 280, 150);
			g.drawLine(275, 155, 280, 150);
			
			g.drawLine(145, 25, 150, 20);
			g.drawLine(155, 25, 150, 20);
			
			g.drawString("O", 140, 162);
			
			g.drawLine(165, 145, 170, 150);
			g.drawLine(165, 155, 170, 150);
			
			g.drawLine(145, 135, 150, 130);
			g.drawLine(155, 135, 150, 130);
		}
		
		if (etape == 1)
		{
			g.setColor(new Color(0, 0, 0));
			g.drawRect(coordXPoint1 + 150, (coordYPoint1 - 150) * -1, 1, 1);
		}
		
		if (etape == 2)
		{
			g.setColor(new Color(0, 0, 0));
			g.drawRect(coordXPoint2 + 150, (coordYPoint2 - 150) * -1, 1, 1);
		}
		
		if (etape == 3)
		{
			g.setColor(new Color(0, 0, 0));
			for (int i = 0; i < 300; i++)
			{
				for (int j = 0; j < 300; j++)
				{
					int newJ = (j - 150) * -1;
					int newI = (i - 150);
					if ((newJ - (coefDir1 * newI) - (absOr1 * 20)) < 0.5f && (newJ - (coefDir1 * newI) - (absOr1 * 20)) > -0.5f)
						g.drawRect(i, j, 1, 1);
				}
			}
		}
		
		if (etape == 4)
		{
			g.setColor(new Color(0, 0, 0));
			g.drawRect(coordXPoint3 + 150, (coordYPoint3 - 150) * -1, 1, 1);
		}
		
		if (etape == 5)
		{
			g.setColor(new Color(0, 0, 0));
			for (int i = 0; i < 300; i++)
			{
				for (int j = 0; j < 300; j++)
				{
					int newJ = (j - 150) * -1;
					int newI = (i - 150);
					if ((newJ - (coefDir2 * newI) - (absOr2 * 20)) < 0.5f && (newJ - (coefDir2 * newI) - (absOr2 * 20)) > -0.5f)
						g.drawRect(i, j, 1, 1);
				}
			}
		}
		
		if (etape > 6)
		{
			g.setColor(Color.red);
			g.drawRect(pointToDrawX, pointToDrawY, 1, 1);
		}
	}
	
	public String CalculEqDroite1()
	{
		coefDir1 = (float) ((float) (coordYPoint2 - coordYPoint1)) / ((float) (coordXPoint2 - coordXPoint1));
		absOr1 =  (float) ((coordYPoint1 - (coordXPoint1 * coefDir1)) / 20f);
		return ("y = " + coefDir1 + "x + " + absOr1);
	}
	
	public String CalculEqDroite2()
	{
		coefDir2 = (float) (-1 / coefDir1);
		absOr2 =  (float) ((coordYPoint3 - (coordXPoint3 * coefDir2)) / 20f);
		return ("y = " + coefDir2 + "x + " + absOr2);
	}
	
	public void mouseClicked(MouseEvent e)
	{
		String message = "";
		
		if (etape == 0)
		{
			coordXPoint1 = e.getX() - 150;
			coordYPoint1 = (e.getY() - 150) * -1;
			message = "Cliquez pour placer le second point";
		}
		
		if (etape == 1)
		{
			coordXPoint2 = e.getX() - 150;
			coordYPoint2 = (e.getY() - 150) * -1;
			message = "Cliquez pour tracer la droite";
		}
		
		if (etape == 2)
		{
			eqDroite1 = CalculEqDroite1();
			message = "L'équation de la première droite est " + eqDroite1 + "\nCliquez pour placer le point par lequel doit passer la perpendiculaire";
		}
		
		if (etape == 3)
		{
			coordXPoint3 = e.getX() - 150;
			coordYPoint3 = (e.getY() - 150) * -1;
			message = "Cliquez pour tracer la droite perpendiculaire";
		}
		
		if (etape == 4)
		{
			eqDroite2 = CalculEqDroite2();
			RobotThread robotThread = new RobotThread(this);
			message = "L'équation de sa perpendiculaire droite est " + eqDroite2;
		}
		
		if (etape >= 5)
		{
			pointToDrawX = (int) e.getX();
			pointToDrawY = (int) e.getY();
		}
		
		etape++;
		this.repaint();
		
		//JOptionPane.showMessageDialog(null, message);
	}
	
	public void mousePressed(MouseEvent e)
	{
	
	}
	
	public void mouseReleased(MouseEvent e)
	{
	
	}
	
	public void mouseExited(MouseEvent e)
	{
	
	}
	
	public void mouseEntered(MouseEvent e)
	{
	
	}
}

class RobotThread extends Thread
{
	JPanel jPanel1;
	
	public RobotThread(JPanel jPanel_arg)
	{
		jPanel1 = jPanel_arg;
		this.start();
	}
	
	public void run()
	{
		try
		{
			Robot robot = new Robot();
			
			for (int i = 0; i < 30; i++) 
	        { 
	            robot.mouseMove((int)jPanel1.getLocationOnScreen().getX() + (i * 10), (int)jPanel1.getLocationOnScreen().getY() + 120);
				this.sleep(1000);
	        }
		}		
        catch(Exception e)
		{ 
			e.printStackTrace(); 
        } 
	}
}

Bonne chance

Niroken

Hmm ah ui comme jai un peu merdouillé dans les indices
ca n affichera des points qu au second/troisième clic
après le déplacement de la souris:)

Mais ca va pas arréter le valeureux guerrier que tu es :D