diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a818314fefa41afad001f9d5e79d4d28946a98f7
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectRootManager" version="2" project-jdk-name="17" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2bc891e500f57d724fd01116ec29becdcf1c026d
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/core.iml" filepath="$PROJECT_DIR$/core.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..35eb1ddfbbc029bcab630581847471d7f238ec53
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8d61c8e3e5b28ba2c6e6c4c1fdd8999e67946c27
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="AutoImportSettings">
+    <option name="autoReloadType" value="SELECTIVE" />
+  </component>
+  <component name="ChangeListManager">
+    <list default="true" id="d7618c8d-68f5-4749-ad72-9e4faa130ff9" name="Changes" comment="">
+      <change afterPath="$PROJECT_DIR$/src/example/randomants/Ant.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/example/randomants/AntHill.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/example/randomants/MainAnt.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/example/randomants/ressources/ant.png" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/example/randomants/ressources/ant_dead.png" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/mas/ui/VUI.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/mas/ui/drawables/Drawable.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/mas/ui/drawables/DrawableCircle.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/mas/ui/drawables/DrawableImage.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/mas/ui/drawables/DrawableLine.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/mas/ui/drawables/DrawableOval.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/mas/ui/drawables/DrawablePoint.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/mas/ui/drawables/DrawableRectangle.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/mas/ui/drawables/DrawableString.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/example/philosophes/Dechets.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/example/philosophes/Dechets.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/example/philosophes/MainPhilosophe.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/example/philosophes/MainPhilosophe.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/example/philosophes/Philosophe.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/example/philosophes/Philosophe.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/mas/core/Agent.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/mas/core/Agent.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/mas/core/Cyclable.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/mas/core/Cyclable.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/mas/environment/TwoDContinuosGrid.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/mas/environment/TwoDContinuosGrid.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/mas/implementation/base/schedulers/AsyncCycling.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/mas/implementation/base/schedulers/AsyncCycling.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/mas/implementation/base/schedulers/FairCycling.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/mas/implementation/base/schedulers/FairCycling.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/mas/implementation/base/schedulers/TwoDCycling.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/mas/implementation/base/schedulers/TwoDCycling.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/mas/ui/SchedulerToolbar.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/mas/ui/SchedulerToolbar.java" afterDir="false" />
+    </list>
+    <option name="SHOW_DIALOG" value="false" />
+    <option name="HIGHLIGHT_CONFLICTS" value="true" />
+    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+    <option name="LAST_RESOLUTION" value="IGNORE" />
+  </component>
+  <component name="Git.Settings">
+    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
+  </component>
+  <component name="MarkdownSettingsMigration">
+    <option name="stateVersion" value="1" />
+  </component>
+  <component name="ProjectId" id="2AsSPACnMPcfJVj1FTH6jpS1pV5" />
+  <component name="ProjectViewState">
+    <option name="hideEmptyMiddlePackages" value="true" />
+    <option name="showLibraryContents" value="true" />
+  </component>
+  <component name="PropertiesComponent"><![CDATA[{
+  "keyToString": {
+    "RunOnceActivity.OpenProjectViewOnStart": "true",
+    "RunOnceActivity.ShowReadmeOnStart": "true",
+    "WebServerToolWindowFactoryState": "false",
+    "last_opened_file_path": "C:/Users/David/Desktop/AmakGit/core/src/mas",
+    "node.js.detected.package.eslint": "true",
+    "node.js.detected.package.tslint": "true",
+    "node.js.selected.package.eslint": "(autodetect)",
+    "node.js.selected.package.tslint": "(autodetect)",
+    "nodejs_package_manager_path": "npm"
+  }
+}]]></component>
+  <component name="RecentsManager">
+    <key name="CopyFile.RECENT_KEYS">
+      <recent name="C:\Users\David\Desktop\AmakGit\core\src\mas" />
+      <recent name="C:\Users\David\Desktop\AmakGit\core\src\example\randomants" />
+    </key>
+  </component>
+  <component name="RunManager" selected="Application.MainAnt">
+    <configuration name="MainAnt" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
+      <option name="MAIN_CLASS_NAME" value="example.randomants.MainAnt" />
+      <module name="core" />
+      <extension name="coverage">
+        <pattern>
+          <option name="PATTERN" value="example.randomants.*" />
+          <option name="ENABLED" value="true" />
+        </pattern>
+      </extension>
+      <method v="2">
+        <option name="Make" enabled="true" />
+      </method>
+    </configuration>
+    <configuration name="Philosophes" type="Application" factoryName="Application">
+      <option name="MAIN_CLASS_NAME" value="example.philosophes.MainPhilosophe" />
+      <module name="core" />
+      <method v="2">
+        <option name="Make" enabled="true" />
+      </method>
+    </configuration>
+    <list>
+      <item itemvalue="Application.Philosophes" />
+      <item itemvalue="Application.MainAnt" />
+    </list>
+    <recent_temporary>
+      <list>
+        <item itemvalue="Application.MainAnt" />
+      </list>
+    </recent_temporary>
+  </component>
+  <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
+  <component name="TaskManager">
+    <task active="true" id="Default" summary="Default task">
+      <changelist id="d7618c8d-68f5-4749-ad72-9e4faa130ff9" name="Changes" comment="" />
+      <created>1655796773469</created>
+      <option name="number" value="Default" />
+      <option name="presentableId" value="Default" />
+      <updated>1655796773469</updated>
+      <workItem from="1655796774853" duration="87000" />
+      <workItem from="1655796884483" duration="12176000" />
+    </task>
+    <servers />
+  </component>
+  <component name="TypeScriptGeneratedFilesManager">
+    <option name="version" value="3" />
+  </component>
+  <component name="Vcs.Log.Tabs.Properties">
+    <option name="TAB_STATES">
+      <map>
+        <entry key="MAIN">
+          <value>
+            <State />
+          </value>
+        </entry>
+      </map>
+    </option>
+  </component>
+</project>
\ No newline at end of file
diff --git a/src/example/philosophes/Dechets.java b/src/example/philosophes/Dechets.java
index 465901d39d1ff2230c736c945573842291613ec9..9a6028d3382fcba772704add9dae66a24f189a03 100644
--- a/src/example/philosophes/Dechets.java
+++ b/src/example/philosophes/Dechets.java
@@ -3,13 +3,11 @@ package example.philosophes;
 import mas.core.Cyclable;
 import mas.core.Schedulable;
 
-import java.util.concurrent.atomic.AtomicInteger;
-
 public class Dechets implements Cyclable {
 
     private int id;
 
-    Schedulable scheduleur = null;
+    Schedulable scheduler = null;
 
     public Dechets(int _id){
         id = _id;
@@ -17,7 +15,7 @@ public class Dechets implements Cyclable {
     }
         @Override
     public void cycle() {
-        System.out.println("je suis le dechet n°" + id);
+        /*System.out.println("je suis le dechet n°" + id);*/
     }
 
     @Override
@@ -26,8 +24,8 @@ public class Dechets implements Cyclable {
     }
 
     @Override
-    public void setScheduleur(Schedulable _scheduleur) {
-        scheduleur = _scheduleur;
+    public void setScheduler(Schedulable _scheduler) {
+        scheduler = _scheduler;
     }
 
     @Override
diff --git a/src/example/philosophes/MainPhilosophe.java b/src/example/philosophes/MainPhilosophe.java
index c1b976fda9ae4396f2dc692eb0f6ccdfd1f19360..83acbcb244e4adaea6edc4b64fff998d421c0ff9 100644
--- a/src/example/philosophes/MainPhilosophe.java
+++ b/src/example/philosophes/MainPhilosophe.java
@@ -1,9 +1,7 @@
 package example.philosophes;
 
 import mas.core.Schedulable;
-import mas.implementation.base.schedulers.TwoDCycling;
-import mas.ui.MainWindow;
-import mas.ui.SchedulerToolbar;
+import mas.implementation.base.schedulers.FairCycling;
 
 public class MainPhilosophe {
 
@@ -29,16 +27,16 @@ public class MainPhilosophe {
             philosophes[i].setRightPhilosophe(philosophes[(i+1) % nAgents]);
         }
 
-        Schedulable scheduleur = new FairCycling(philosophes);
-        //scheduleur.setSleep(500);
-        scheduleur.start();
+        Schedulable scheduler = new FairCycling(philosophes);
+        scheduler.setSleep(2);
+        scheduler.start();
 
         try {
             Thread.sleep(2000);
         } catch (InterruptedException e) {
             throw new RuntimeException(e);
         }
-        scheduleur.pause();
+        scheduler.pause();
 
         try {
             Thread.sleep(2000);
@@ -46,18 +44,18 @@ public class MainPhilosophe {
             throw new RuntimeException(e);
         }
 
-        scheduleur.resume();
+        scheduler.resume();
 
         try {
-            Thread.sleep(2000);
+            Thread.sleep(5000);
         } catch (InterruptedException e) {
             throw new RuntimeException(e);
         }
 
-        scheduleur.stop();
+        scheduler.stop();
 
 
         final long endTime = System.nanoTime();
-        System.out.println("Total execution time: " + (endTime / 1000000 - startTime / 1000000) + " microseconds");*/
+        System.out.println("Total execution time: " + (endTime / 1000000 - startTime / 1000000) + " microseconds");
     }
 }
diff --git a/src/example/philosophes/Philosophe.java b/src/example/philosophes/Philosophe.java
index 761f71765995663e71cf643f878c40179f35b9c3..8e69a2f883dfa593621e42f48b0c0d2b2c82aeef 100644
--- a/src/example/philosophes/Philosophe.java
+++ b/src/example/philosophes/Philosophe.java
@@ -32,7 +32,7 @@ public class Philosophe extends Agent {
      */
     private int id;
 
-    private Schedulable scheduleur;
+    private Schedulable scheduler;
 
     /**
      * States philosophers can be in
@@ -120,7 +120,7 @@ public class Philosophe extends Agent {
         //System.out.println("Philospher n°" + id + " / State " + state);
         System.out.println(
                 "\tPhilosopher num " + id + " : " + state + " / " + criticallity + " / " + eatenPastas
-                 /*+ "\n\t\t Right Fk : " + rightFork.getTakenBy().getId() + " / Left Fk : " + leftFork.getTakenBy().getId()*/
+                /* + "\n\t\t Right Fk : " + rightFork.getTakenBy().getId() + " / Left Fk : " + leftFork.getTakenBy().getId()*/
         );
     }
 
@@ -147,7 +147,7 @@ public class Philosophe extends Agent {
     @Override
     public void act() {
         //System.out.println("Philosopher num " + id + " act");
-        scheduleur.addCyclable(new Dechets(id));
+        scheduler.addCyclable(new Dechets(id));
     }
 
     @Override
@@ -195,12 +195,12 @@ public class Philosophe extends Agent {
         this.rightPhilosophe = rightPhilosophe;
     }
 
-    public void setScheduleur(Schedulable scheduleur) {
-        this.scheduleur = scheduleur;
+    public void setScheduler(Schedulable scheduler) {
+        this.scheduler = scheduler;
     }
 
-    public Schedulable getScheduleur() {
-        return scheduleur;
+    public Schedulable getScheduler() {
+        return scheduler;
     }
 
     @Override
diff --git a/src/example/randomants/Ant.java b/src/example/randomants/Ant.java
new file mode 100644
index 0000000000000000000000000000000000000000..5f64c9961e5fa31dc4080e2764d4cef8a6952433
--- /dev/null
+++ b/src/example/randomants/Ant.java
@@ -0,0 +1,95 @@
+package example.randomants;
+
+import mas.core.Agent;
+import mas.environment.TwoDContinuosGrid;
+import mas.ui.VUI;
+import mas.ui.drawables.DrawableImage;
+
+import java.util.Random;
+
+public class Ant extends Agent {
+
+    private static int numberOfAnts = 0;
+
+    public int id;
+    /**
+     * X coordinate of the ant in the world
+     */
+    public double dx;
+    /**
+     * Y coordinate of the ant in the world
+     */
+    public double dy;
+
+    public boolean mustDie = false;
+    /**
+     * Angle in radians
+     */
+    private double angle = Math.random() * Math.PI * 2;
+    private DrawableImage image;
+
+    TwoDContinuosGrid environnement;
+
+    /**
+     * Constructor of the ant
+     *
+     * @param startX
+     *            Initial X coordinate
+     * @param startY
+     *            Initial Y coordinate
+     */
+    public Ant(int _id, double startX, double startY, TwoDContinuosGrid _environnement) {
+        numberOfAnts++;
+        id = _id;
+        dx = startX;
+        dy = startY;
+        environnement = _environnement;
+        image = VUI.get().createImage(dx, dy, "src/example/randomants/ressources/ant.png");
+    }
+
+    /**
+     * Move in a random direction
+     */
+    @Override
+    public void decide() {
+        double random = new Random().nextGaussian();
+
+        angle += random * 0.1;
+        dx += Math.cos(angle);
+        dy += Math.sin(angle);
+        while (dx >= environnement.getWidth() / 2)
+            dx -= environnement.getWidth();
+        while (dy >= environnement.getHeight() / 2)
+            dy -= environnement.getHeight();
+        while (dx < -environnement.getWidth() / 2)
+            dx += environnement.getWidth();
+        while (dy < -environnement.getHeight() / 2)
+            dy += environnement.getHeight();
+    }
+
+    @Override
+    public boolean terminate() {
+        return mustDie;
+    }
+
+    @Override
+    public void act() {
+        image.move(dx,dy);
+        image.setAngle(angle);
+
+        if (new Random().nextDouble() < 0.001) {
+            scheduler.addCyclable(new Ant(id * 10,dx, dy, environnement));
+        }
+
+        if (new Random().nextDouble() < 0.001) {
+            image.setFilename("src/example/randomants/ressources/ant_dead.png");
+            numberOfAnts--;
+            mustDie = true;
+        }
+        //System.out.println("Ant n°" + id + " / x = " + dx + " / y = " + dy);
+    }
+
+    public static int getNumberOfAnts() {
+        return numberOfAnts;
+    }
+}
diff --git a/src/example/randomants/AntHill.java b/src/example/randomants/AntHill.java
new file mode 100644
index 0000000000000000000000000000000000000000..771a2134d1f2a63a092be2ce6ac50759c3e37ff9
--- /dev/null
+++ b/src/example/randomants/AntHill.java
@@ -0,0 +1,31 @@
+package example.randomants;
+
+import mas.ui.VUI;
+import mas.ui.drawables.DrawableRectangle;
+import mas.ui.drawables.DrawableString;
+
+import java.awt.*;
+
+public class AntHill {
+
+    public DrawableString antsCountLabel;
+
+    public AntHill(int _weight, int _height){
+
+        DrawableRectangle d = VUI.get().createRectangle(0, 0, _weight, _height);
+        d.setStrokeOnly();
+
+        VUI.get().createRectangle(90, 20, 180, 40).setColor(new Color(0.9f, 0.9f, 0.9f, 0.8f)).setFixed().setLayer(5);
+
+        VUI.get().createImage(20, 20, "src/example/randomants/ressources/ant.png").setFixed().setLayer(10);
+        antsCountLabel = (DrawableString) VUI.get().createString(45, 25, "Ants count").setFixed().setLayer(10);
+    }
+
+    public DrawableString getAntsCountLabel() {
+        return antsCountLabel;
+    }
+
+    public void setAntsCountLabel(DrawableString _antsCountLabel) {
+        antsCountLabel = _antsCountLabel;
+    }
+}
diff --git a/src/example/randomants/MainAnt.java b/src/example/randomants/MainAnt.java
new file mode 100644
index 0000000000000000000000000000000000000000..9afcb72c75ab6641cae77b8985243cdf9cb5bd82
--- /dev/null
+++ b/src/example/randomants/MainAnt.java
@@ -0,0 +1,34 @@
+package example.randomants;
+
+import mas.core.Agent;
+import mas.environment.TwoDContinuosGrid;
+import mas.implementation.base.schedulers.TwoDCycling;
+import mas.ui.MainWindow;
+import mas.ui.SchedulerToolbar;
+
+public class MainAnt {
+
+    public static void main(String[] args) {
+
+        int widht = 800;
+        int height = 600;
+
+
+        AntHill hill = new AntHill(widht, height);
+
+        TwoDContinuosGrid env = new TwoDContinuosGrid(widht, height);
+
+        int nAgents = 50;
+
+        Agent[] ants = new Ant[nAgents];
+
+        for(int i = 0; i<nAgents ; i++){
+            ants[i] = new Ant(i+1,0,0,env);
+        }
+
+        TwoDCycling scheduler = new TwoDCycling(ants);
+
+        MainWindow.instance();
+        MainWindow.addToolbar(new SchedulerToolbar("Amas", scheduler));
+    }
+}
diff --git a/src/example/randomants/ressources/ant.png b/src/example/randomants/ressources/ant.png
new file mode 100644
index 0000000000000000000000000000000000000000..913a361085cac804f7afe2e16cf7bbbf7ad273c4
Binary files /dev/null and b/src/example/randomants/ressources/ant.png differ
diff --git a/src/example/randomants/ressources/ant_dead.png b/src/example/randomants/ressources/ant_dead.png
new file mode 100644
index 0000000000000000000000000000000000000000..cf9a4b9b12215335b24d56daf459f3822db61b40
Binary files /dev/null and b/src/example/randomants/ressources/ant_dead.png differ
diff --git a/src/mas/core/Agent.java b/src/mas/core/Agent.java
index d4b955b3308628c5c1625b3674b8eb2ef433c10e..eb85fde476e067e1f15ee042bafd3500a3efaaa9 100644
--- a/src/mas/core/Agent.java
+++ b/src/mas/core/Agent.java
@@ -2,7 +2,7 @@ package mas.core;
 
 public class Agent implements ThreeStepCyclable{
 
-    private Schedulable scheduleur;
+    protected Schedulable scheduler;
 
     @Override
     public void perceive() {
@@ -25,7 +25,7 @@ public class Agent implements ThreeStepCyclable{
     }
 
     @Override
-    public void setScheduleur(Schedulable _scheduleur) {
-        scheduleur = _scheduleur;
+    public void setScheduler(Schedulable _scheduler) {
+        scheduler = _scheduler;
     }
 }
diff --git a/src/mas/core/Cyclable.java b/src/mas/core/Cyclable.java
index c272b066b98e525ab4f2190f4720eb4ea3896fe6..05a7fde131c41402cd9f5e804ebadbca4863f54d 100644
--- a/src/mas/core/Cyclable.java
+++ b/src/mas/core/Cyclable.java
@@ -19,5 +19,5 @@ public interface Cyclable {
     /**
      * TODO
      */
-    void setScheduleur(Schedulable _scheduleur);
+    void setScheduler(Schedulable _scheduler);
 }
diff --git a/src/mas/environment/TwoDContinuosGrid.java b/src/mas/environment/TwoDContinuosGrid.java
index 4ae7f991c0e1ea0a73e91d8bcc034ceafde4815d..5cc7896232d1b82233c79930fd9f49c1bf6bb431 100644
--- a/src/mas/environment/TwoDContinuosGrid.java
+++ b/src/mas/environment/TwoDContinuosGrid.java
@@ -2,4 +2,20 @@ package mas.environment;
 
 public class TwoDContinuosGrid {
 
+    private int width;
+    private int height;
+
+    public TwoDContinuosGrid(int _width, int _height){
+        height = _height;
+        width = _width;
+    }
+
+    public int getHeight() {
+        return height;
+    }
+
+    public int getWidth() {
+        return width;
+    }
+
 }
diff --git a/src/mas/implementation/base/schedulers/AsyncCycling.java b/src/mas/implementation/base/schedulers/AsyncCycling.java
index 99c821b41f5e0bc580e8715d4fc3feafbf412b46..9d131094c09d0b295fb00282cdbcd2574775777e 100644
--- a/src/mas/implementation/base/schedulers/AsyncCycling.java
+++ b/src/mas/implementation/base/schedulers/AsyncCycling.java
@@ -23,7 +23,7 @@ public class AsyncCycling implements Schedulable {
 
         for(Cyclable cyclable : _cyclables){
             cyclables.add(cyclable);
-            cyclable.setScheduleur(this);
+            cyclable.setScheduler(this);
         }
     }
 
@@ -64,7 +64,7 @@ public class AsyncCycling implements Schedulable {
     @Override
     public void addCyclable(Cyclable cyclable) {
         cyclables.add(cyclable);
-        cyclable.setScheduleur(this);
+        cyclable.setScheduler(this);
 
         if(!mustStop){
             executor.execute(() -> {
diff --git a/src/mas/implementation/base/schedulers/FairCycling.java b/src/mas/implementation/base/schedulers/FairCycling.java
index aeb42f01d4ddecc62f7d69740c01c5cdf944bd41..6d283eb96e462665e53b10b674baaf9a383c8cf2 100644
--- a/src/mas/implementation/base/schedulers/FairCycling.java
+++ b/src/mas/implementation/base/schedulers/FairCycling.java
@@ -3,10 +3,9 @@ package mas.implementation.base.schedulers;
 import mas.core.Cyclable;
 import mas.core.Schedulable;
 
-import java.util.LinkedHashSet;
-import java.util.Queue;
-import java.util.Set;
+import java.util.*;
 import java.util.concurrent.*;
+import java.util.function.Consumer;
 
 /**
  * Chaque agent execute exactement 1 cycle pour chaque cycle systeme
@@ -40,28 +39,32 @@ public class FairCycling implements Schedulable {
 
     @Override
     public void start() {
-        System.out.println("Je fait start");
-        new Thread(() -> doCycle()).start();
+        //System.out.println("Je fait start");
+        executor.execute(() -> {
+            doCycle();
+        });
     }
 
     @Override
     public void stop() {
-        System.out.println("Je fait stop");
+        //System.out.println("Je fait stop");
         mustStop = true;
         executor.shutdown();
     }
 
     @Override
     public void pause() {
-        System.out.println("Je fait pause");
+        //System.out.println("Je fait pause");
         pauseLatch = new CountDownLatch(1);
         mustPause = true;
     }
 
     @Override
     public void resume() {
-        System.out.println("Je fait resume");
-        pauseLatch.countDown();
+        //System.out.println("Je fait resume");
+        if(pauseLatch != null){
+            pauseLatch.countDown();
+        }
     }
 
     @Override
@@ -69,10 +72,14 @@ public class FairCycling implements Schedulable {
         return false;
     }
 
+    protected void onCycleEnds() {
+
+    }
+
     @Override
     public void addCyclable(Cyclable cyclable){
         //System.out.println("Je fait addCyclebles : " + cyclable.toString());
-        cyclable.setScheduleur(this);
+        cyclable.setScheduler(this);
         pendingToAddCyclables.add(cyclable);
     }
 
@@ -87,12 +94,10 @@ public class FairCycling implements Schedulable {
     }
 
     protected void step() {
-        System.out.println("Je fait step");
+        //System.out.println("Je fait step");
         nbOfCycles++;
         System.out.println("cycle systeme " + nbOfCycles);
 
-        //System.out.println(pendingToAddCyclables.size() + " : " + pendingToAddCyclables);
-
         treatPendingCyclables();
 
         latch = new CountDownLatch(cyclables.size());
@@ -102,13 +107,10 @@ public class FairCycling implements Schedulable {
             executor.execute(() -> {
                 cyclable.cycle();
                 if(!cyclable.terminate()){
-                    //System.out.println("\t\t" + cyclable.toString() + " je fait pendingToAdd");
                     pendingToAddCyclables.add(cyclable);
                 }
-
                 latch.countDown();
             });
-
         }
 
         if (getSleep() != 0) {
@@ -126,10 +128,12 @@ public class FairCycling implements Schedulable {
         }
 
         cyclables.clear();
+
+        onCycleEnds();
     }
 
     protected void doCycle() {
-        System.out.println("Je fait doCycle");
+        //System.out.println("Je fait doCycle");
         step();
         if(stopCondition()){
             this.stop();
@@ -148,7 +152,8 @@ public class FairCycling implements Schedulable {
     }
 
     private void treatPendingCyclables() {
-        while (!pendingToAddCyclables.isEmpty())
-            cyclables.add(pendingToAddCyclables.poll());
+        Queue<Cyclable> buffer = new ConcurrentLinkedQueue<>(pendingToAddCyclables);
+        cyclables.addAll(buffer);
+        pendingToAddCyclables.clear();
     }
 }
diff --git a/src/mas/implementation/base/schedulers/TwoDCycling.java b/src/mas/implementation/base/schedulers/TwoDCycling.java
index 0c9067e8653e0506601e9af239ae533373d0f1f6..f3d1478cb1e33eb51310059e5fc1a425e3d4c1a4 100644
--- a/src/mas/implementation/base/schedulers/TwoDCycling.java
+++ b/src/mas/implementation/base/schedulers/TwoDCycling.java
@@ -1,6 +1,7 @@
 package mas.implementation.base.schedulers;
 
 import mas.core.Cyclable;
+import mas.ui.VUI;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -12,7 +13,7 @@ public class TwoDCycling extends FairCycling{
     /**
      * The state of the scheduler {@link State}
      */
-    private State state;
+    private State state = State.PENDING_START;
 
     /**
      * Method that is called when the scheduler stops
@@ -25,6 +26,10 @@ public class TwoDCycling extends FairCycling{
      */
 
     public enum State {
+        /**
+         * The scheduler is waiting to start
+         */
+        PENDING_START,
         /**
          * The scheduler is running
          */
@@ -32,11 +37,7 @@ public class TwoDCycling extends FairCycling{
         /**
          * The scheduler is paused
          */
-        IDLE,
-        /**
-         * The scheduler is expected to stop at the end at the current cycle
-         */
-        PENDING_STOP
+        IDLE
 
     }
     private List<Consumer<TwoDCycling>> onChange = new ArrayList<>();
@@ -68,22 +69,30 @@ public class TwoDCycling extends FairCycling{
     }
 
     public void doOneCycle() {
-        System.out.println("Je fait doOneCycle");
-        step();
-        if(stopCondition()){
-            this.stop();
-        }
-
-        if (!mustStop) {
-            this.pause();
-        }
+        executor.execute(() -> {
+            step();
+            if(stopCondition()){
+                this.stop();
+            }
+
+            if (!mustStop) {
+                this.pause();
+            }
+        });
     }
     public void startWithSleep(int _sleep){
-        System.out.println("Je commence startWithSleep(" + _sleep + ")");
+        //System.out.println("Je commence startWithSleep(" + _sleep + ")");
         setSleep(_sleep);
-        state = State.RUNNING;
-        resume();
-        executor.execute(() -> doCycle());
+
+
+        switch (state){
+            case PENDING_START -> {
+                start();
+            }
+            default -> {
+                resume();
+            }
+        }
     }
 
 
@@ -94,21 +103,21 @@ public class TwoDCycling extends FairCycling{
     @Override
     public void start() {
         state = State.RUNNING;
-        new Thread(() -> doCycle()).start();
+        super.start();
     }
 
     @Override
     public void pause() {
         state = State.IDLE;
-        pauseLatch = new CountDownLatch(1);
+        if(pauseLatch == null){
+            pauseLatch = new CountDownLatch(1);
+        }
         mustPause = true;
     }
 
     @Override
     public void resume() {
-        if(pauseLatch != null){
-            pauseLatch.countDown();
-        }
+        super.resume();
         state = State.RUNNING;
     }
 }
diff --git a/src/mas/ui/SchedulerToolbar.java b/src/mas/ui/SchedulerToolbar.java
index 69ea3523befc110b5b2376beff25302dbce83116..5cd2b47d432c59e356f78e7c988ac880579f99b0 100644
--- a/src/mas/ui/SchedulerToolbar.java
+++ b/src/mas/ui/SchedulerToolbar.java
@@ -3,7 +3,6 @@ package mas.ui;
 import mas.implementation.base.schedulers.TwoDCycling;
 
 import javax.swing.*;
-import javax.swing.event.ChangeListener;
 import java.awt.*;
 import java.util.Hashtable;
 
diff --git a/src/mas/ui/VUI.java b/src/mas/ui/VUI.java
new file mode 100644
index 0000000000000000000000000000000000000000..ee38e122d5dc92716391b71d44bf6bfd612bd889
--- /dev/null
+++ b/src/mas/ui/VUI.java
@@ -0,0 +1,507 @@
+package mas.ui;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+import javax.swing.border.BevelBorder;
+
+import mas.ui.drawables.*;
+
+/**
+ * 
+ * Vectorial UI: This class allows to create dynamic rendering with zoom and
+ * move capacities
+ * 
+ * @author perles
+ *
+ */
+public class VUI {
+	/**
+	 * List of objects currently being drawn by the VUI
+	 */
+	private List<Drawable> drawables = new ArrayList<>();
+	/**
+	 * Lock to avoid concurrent modification on the list {@link #drawables}
+	 */
+	private ReentrantLock drawablesLock = new ReentrantLock();
+
+	/**
+	 * A static map to facilitate access to different instances of VUI
+	 */
+	private static Map<String, VUI> instances = new HashMap<>();
+
+	/**
+	 * The horizontal offset of the drawing zone. Used to allow the user to move the
+	 * view.
+	 */
+	private double worldOffsetX;
+
+	/**
+	 * The vertical offset of the drawing zone. Used to allow the user to move the
+	 * view.
+	 */
+	private double worldOffsetY;
+
+	/**
+	 * The last horizontal position of the mouse when dragging
+	 */
+	protected Integer lastDragX;
+
+	/**
+	 * The last vertical position of the mouse when dragging
+	 */
+	protected Integer lastDragY;
+
+	/**
+	 * The main panel of the VUI
+	 */
+	private JPanel panel;
+
+	/**
+	 * The canvas on which all is drawn
+	 */
+	private JPanel canvas;
+
+	/**
+	 * Label aiming at showing information about the VUI (zoom and offset)
+	 */
+	private JLabel statusLabel;
+
+	/**
+	 * The default value of the {@link #zoom}
+	 */
+	private double defaultZoom = 100;
+	/**
+	 * The default horizontal position of the view
+	 */
+	private double defaultWorldCenterX = 0;
+	/**
+	 * The default vertical position of the view
+	 */
+	private double defaultWorldCenterY = 0;
+	/**
+	 * The value of the zoom. 100 means 1/1 scale
+	 */
+	protected double zoom = defaultZoom;
+
+	/**
+	 * The horizontal position of the view
+	 */
+	private double worldCenterX = defaultWorldCenterX;
+
+	/**
+	 * The vertical position of the view
+	 */
+	private double worldCenterY = defaultWorldCenterY;
+
+	/**
+	 * Get the default VUI
+	 * 
+	 * @return the default VUI
+	 */
+	public static VUI get() {
+		return get("Default");
+	}
+
+	/**
+	 * Create or get a VUI
+	 * 
+	 * @param id
+	 *            The unique id of the VUI
+	 * @return The VUI with id "id"
+	 */
+	public static VUI get(String id) {
+		if (!instances.containsKey(id)) {
+			VUI value = new VUI(id);
+			instances.put(id, value);
+			return value;
+		}
+		return instances.get(id);
+	}
+
+	/**
+	 * Constructor of the VUI. This one is private as it can only be created through
+	 * static method.
+	 * 
+	 * @param title
+	 *            The title used for the vui
+	 */
+	private VUI(String title) {
+		panel = new JPanel(new BorderLayout());
+
+		JPanel statusPanel = new JPanel();
+		statusPanel.setBorder(new BevelBorder(BevelBorder.LOWERED));
+		statusPanel.setLayout(new BoxLayout(statusPanel, BoxLayout.X_AXIS));
+		statusLabel = new JLabel("status");
+		statusLabel.setHorizontalAlignment(SwingConstants.LEFT);
+		statusPanel.add(statusLabel);
+		JButton resetButton = new JButton("Reset");
+		resetButton.addActionListener(l -> {
+			zoom = defaultZoom;
+			worldCenterX = defaultWorldCenterX;
+			worldCenterY = defaultWorldCenterY;
+			updateCanvas();
+		});
+		statusPanel.add(resetButton);
+
+		canvas = new JPanel() {
+
+			/**
+			 * 
+			 */
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			protected void paintComponent(Graphics g) {
+
+				final Graphics2D g2 = (Graphics2D) g;
+
+				final int w = getSize().width;
+				final int h = getSize().height;
+
+				setWorldOffsetX(worldCenterX + screenToWorldDistance(w / 2));
+				setWorldOffsetY(worldCenterY + screenToWorldDistance(h / 2));
+
+				g.setColor(new Color(0.96f, 0.96f, 0.96f));
+				g.fillRect(0, 0, w, h);
+				drawablesLock.lock();
+				Collections.sort(drawables, (o1, o2) -> o1.getLayer() - o2.getLayer());
+				for (Drawable d : drawables) {
+					d.onDraw(g2);
+				}
+				drawablesLock.unlock();
+			}
+		};
+		canvas.addMouseListener(new MouseListener() {
+
+			@Override
+			public void mouseReleased(MouseEvent e) {
+				// This method is not meant to be used as everything is handled by other methods
+			}
+
+			@Override
+			public void mousePressed(MouseEvent e) {
+
+				lastDragX = e.getX();
+				lastDragY = e.getY();
+			}
+
+			@Override
+			public void mouseExited(MouseEvent e) {
+				lastDragX = null;
+				lastDragY = null;
+			}
+
+			@Override
+			public void mouseEntered(MouseEvent e) {
+				// This method is not meant to be used as everything is handled by other methods
+			}
+
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				// This method is not meant to be used yet
+			}
+		});
+		canvas.addMouseMotionListener(new MouseMotionListener() {
+			@Override
+			public void mouseMoved(MouseEvent e) {
+				// This method is not meant to be used as everything is handled by other methods
+			}
+
+			@Override
+			public void mouseDragged(MouseEvent e) {
+				try {
+					worldCenterX += screenToWorldDistance(e.getX() - lastDragX);
+					worldCenterY += screenToWorldDistance(e.getY() - lastDragY);
+					lastDragX = e.getX();
+					lastDragY = e.getY();
+					updateCanvas();
+				} catch (Exception ez) {
+					// Catch exception occuring when mouse is out of the canvas
+				}
+			}
+		});
+		canvas.addMouseWheelListener(e -> {
+			double wdx = screenToWorldDistance((int) (canvas.getSize().getWidth() / 2 - e.getX()));
+			double wdy = screenToWorldDistance((int) (canvas.getSize().getHeight() / 2 - e.getY()));
+
+			zoom += e.getWheelRotation() * 10;
+			if (zoom < 10)
+				zoom = 10;
+
+			double wdx2 = screenToWorldDistance((int) (canvas.getSize().getWidth() / 2 - e.getX()));
+			double wdy2 = screenToWorldDistance((int) (canvas.getSize().getHeight() / 2 - e.getY()));
+
+			worldCenterX -= wdx2 - wdx;
+			worldCenterY -= wdy2 - wdy;
+			updateCanvas();
+		});
+		canvas.setPreferredSize(new Dimension(800, 600));
+		panel.add(canvas, BorderLayout.CENTER);
+		panel.add(statusPanel, BorderLayout.SOUTH);
+		MainWindow.addTabbedPanel("VUI #" + title, panel);
+
+	}
+
+	/**
+	 * Convert a distance in the world to its equivalent on the screen
+	 * 
+	 * @param d
+	 *            the in world distance
+	 * @return the on screen distance
+	 */
+	public int worldToScreenDistance(double d) {
+		return (int) (d * getZoomFactor());
+	}
+
+	/**
+	 * Convert a distance on the screen to its equivalent in the world
+	 * 
+	 * @param d
+	 *            the on screen distance
+	 * @return the in world distance
+	 */
+	public double screenToWorldDistance(int d) {
+		return ((double) d / getZoomFactor());
+	}
+
+	/**
+	 * Convert a X in the world to its equivalent on the screen
+	 * 
+	 * @param x
+	 *            the X in world
+	 *
+	 * @return the X on screen distance
+	 */
+	public int worldToScreenX(double x) {
+		return (int) ((x + getWorldOffsetX()) * getZoomFactor());
+	}
+
+	/**
+	 * A value that must be multiplied to scale objects
+	 * 
+	 * @return the zoom factor
+	 */
+	public double getZoomFactor() {
+		return zoom / 100;
+	}
+
+	/**
+	 * Convert a Y in the world to its equivalent on the screen
+	 * 
+	 * @param y
+	 *            the Y in world
+	 *
+	 * @return the Y on screen distance
+	 */
+	public int worldToScreenY(double y) {
+		return (int) ((y + getWorldOffsetY()) * getZoomFactor());
+	}
+
+	/**
+	 * Convert a X on the screen to its equivalent in the world
+	 * 
+	 * @param x
+	 *            the X on screen
+	 *
+	 * @return the X in the world distance
+	 */
+	public double screenToWorldX(double x) {
+		return (x) / getZoomFactor() - getWorldOffsetX();
+	}
+
+	/**
+	 * Convert a Y on the screen to its equivalent in the world
+	 * 
+	 * @param y
+	 *            the Y on screen
+	 *
+	 * @return the Y in the world distance
+	 */
+	public double screenToWorldY(double y) {
+		return (y) / getZoomFactor() - getWorldOffsetY();
+	}
+
+	/**
+	 * Add an object to the VUI and repaint it
+	 * 
+	 * @param d
+	 *            the new object
+	 */
+	public void add(Drawable d) {
+		d.setPanel(this);
+		drawablesLock.lock();
+		drawables.add(d);
+		drawablesLock.unlock();
+		updateCanvas();
+	}
+
+	/**
+	 * Refresh the canvas
+	 */
+	public void updateCanvas() {
+		canvas.repaint();
+
+		statusLabel.setText(String.format("Zoom: %.2f Center: (%.2f,%.2f)", zoom, worldCenterX, worldCenterY));
+	}
+
+	/**
+	 * Get the width of the canvas
+	 * 
+	 * @return the canvas width
+	 */
+	public double getCanvasWidth() {
+		return canvas.getSize().getWidth();
+	}
+
+	/**
+	 * Get the height of the canvas
+	 * 
+	 * @return the canvas height
+	 */
+	public double getCanvasHeight() {
+		return canvas.getSize().getHeight();
+	}
+
+	/**
+	 * Get the value that must be added to the X coordinate of in world object
+	 * 
+	 * @return the X offset
+	 */
+	public double getWorldOffsetX() {
+		return worldOffsetX;
+	}
+
+	/**
+	 * Set the value that must be added to the X coordinate of in world object
+	 * 
+	 * @param offsetX
+	 *            the X offset
+	 */
+	public void setWorldOffsetX(double offsetX) {
+		this.worldOffsetX = offsetX;
+	}
+
+	/**
+	 * Get the value that must be added to the Y coordinate of in world object
+	 * 
+	 * @return the Y offset
+	 */
+	public double getWorldOffsetY() {
+		return worldOffsetY;
+	}
+
+	/**
+	 * Set the value that must be added to the Y coordinate of in world object
+	 * 
+	 * @param offsetY
+	 *            the Y offset
+	 */
+	public void setWorldOffsetY(double offsetY) {
+		this.worldOffsetY = offsetY;
+	}
+
+	/**
+	 * Create a point and start rendering it
+	 * 
+	 * @param dx
+	 *            the x coordinate
+	 * @param dy
+	 *            the y coordinate
+	 * @return the point object
+	 */
+	public DrawablePoint createPoint(double dx, double dy) {
+		DrawablePoint drawablePoint = new DrawablePoint(this, dx, dy);
+		add(drawablePoint);
+		return drawablePoint;
+	}
+
+	/**
+	 * Create a rectangle and start rendering it
+	 * 
+	 * @param x
+	 *            the x coordinate
+	 * @param y
+	 *            the y coordinate
+	 * @param w
+	 *            the width
+	 * @param h
+	 *            the height
+	 * @return the rectangle object
+	 */
+	public DrawableRectangle createRectangle(double x, double y, double w, double h) {
+		DrawableRectangle d = new DrawableRectangle(this, x, y, w, h);
+		add(d);
+		return d;
+	}
+
+	/**
+	 * Set the default configuration of the view
+	 * 
+	 * @param zoom
+	 *            the initial zoom value
+	 * @param worldCenterX
+	 *            the initial X center value
+	 * @param worldCenterY
+	 *            the initial Y center value
+	 */
+	public void setDefaultView(double zoom, double worldCenterX, double worldCenterY) {
+		this.zoom = zoom;
+		this.worldCenterX = worldCenterX;
+		this.worldCenterY = worldCenterY;
+		this.defaultZoom = zoom;
+		this.defaultWorldCenterX = worldCenterX;
+		this.defaultWorldCenterY = worldCenterY;
+	}
+
+	/**
+	 * Create an image and start rendering it
+	 * 
+	 * @param dx
+	 *            the x coordinate
+	 * @param dy
+	 *            the y coordinate
+	 * @param filename
+	 *            the filename of the image
+	 * @return the created image
+	 */
+	public DrawableImage createImage(double dx, double dy, String filename) {
+		DrawableImage image = new DrawableImage(this, dx, dy, filename);
+		add(image);
+		return image;
+	}
+
+	/**
+	 * Create a string and start rendering it
+	 * 
+	 * @param dx
+	 *            the x coordinate
+	 * @param dy
+	 *            the y coordinate
+	 * @param text
+	 *            the text to display
+	 * @return the created string
+	 */
+	public DrawableString createString(int dx, int dy, String text) {
+		DrawableString ds = new DrawableString(this, dx, dy, text);
+		add(ds);
+		return ds;
+	}
+}
diff --git a/src/mas/ui/drawables/Drawable.java b/src/mas/ui/drawables/Drawable.java
new file mode 100644
index 0000000000000000000000000000000000000000..251c8c10ed2d8ccc3622c955db6be50790108b5c
--- /dev/null
+++ b/src/mas/ui/drawables/Drawable.java
@@ -0,0 +1,396 @@
+package mas.ui.drawables;
+
+import mas.ui.VUI;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+
+/**
+ * A drawable is an object that can be drawn by the {@link VUI} system
+ * 
+ * @author Alexandre Perles
+ *
+ */
+public abstract class Drawable {
+
+	/**
+	 * The horizontal position of the object
+	 */
+	private double x;
+	/**
+	 * The vertical position of the object
+	 */
+	private double y;
+	/**
+	 * The width of the object
+	 */
+	private double width;
+
+	/**
+	 * Compute the width as it must be displayed on screen. Given the zoom factor,
+	 * the width displayed can be different than the real width.
+	 * 
+	 * @return the width
+	 */
+	public double getRenderedWidth() {
+		if (isFixed())
+			return width;
+		else
+			return vui.worldToScreenDistance(width);
+	}
+
+	/**
+	 * Set the real width of the object
+	 *
+	 * @param width
+	 *            The new width
+	 */
+	public void setWidth(double width) {
+		this.width = width;
+		update();
+	}
+
+	/**
+	 * Compute the height as it must be displayed on screen. Given the zoom factor,
+	 * the height displayed can be different than the real height.
+	 * 
+	 * @return the width
+	 */
+	public double getRenderedHeight() {
+		if (isFixed())
+			return height;
+		else
+			return vui.worldToScreenDistance(height);
+	}
+
+	/**
+	 * Set the real height of the object
+	 * 
+	 * @param height
+	 *            The new height
+	 */
+	public void setHeight(double height) {
+		this.height = height;
+		update();
+	}
+
+	/**
+	 * Get the real width
+	 * 
+	 * @return the real width
+	 */
+	public double getWidth() {
+		return width;
+	}
+
+	/**
+	 * Get the real height
+	 * 
+	 * @return the real height
+	 */
+	public double getHeight() {
+		return height;
+	}
+
+	/**
+	 * The real height
+	 */
+	protected double height;
+
+	/**
+	 * Does only the border must be displayed ?
+	 */
+	protected boolean strokeMode = false;
+
+	/**
+	 * The color of the object
+	 */
+	protected Color color = Color.black;
+	/**
+	 * The VUI on which the object is drawn
+	 */
+	protected VUI vui;
+	/**
+	 * The order of drawing. An higher layer is drawn on top of the other.
+	 */
+	protected int layer = 0;
+	/**
+	 * The angle of rotation of the object
+	 */
+	private double angle;
+	/**
+	 * A fixed object doesn't move with the view. It can be used for HUD
+	 */
+	private boolean fixed = false;
+	/**
+	 * Must the object be drawn ?
+	 */
+	private boolean visible = true;
+
+	/**
+	 * Getter for the fixed attribute
+	 * 
+	 * @return if the obejct is fixed
+	 */
+	public boolean isFixed() {
+		return fixed;
+	}
+
+	/**
+	 * Getter for the angle attribute
+	 * 
+	 * @return the angle
+	 */
+	public double getAngle() {
+		return angle;
+	}
+
+	/**
+	 * Getter for the layer attribute
+	 * 
+	 * @return the layer
+	 */
+	public int getLayer() {
+		return layer;
+	}
+
+	/**
+	 * Set the layer and update
+	 * 
+	 * @param layer
+	 *            the new layer
+	 * @return the object for chained methods
+	 */
+	public Drawable setLayer(int layer) {
+		this.layer = layer;
+		update();
+		return this;
+	}
+
+	/**
+	 * Set the new angle
+	 * 
+	 * @param angle2
+	 *            the new angle
+	 * @return the object for chained methods
+	 */
+	public Drawable setAngle(double angle2) {
+		this.angle = angle2;
+		update();
+		return this;
+	}
+
+	/**
+	 * Constructor of the obejct
+	 * 
+	 * @param vui
+	 *            the VUI on which the object must be drawn
+	 * @param dx
+	 *            the x real position
+	 * @param dy
+	 *            the y real position
+	 * @param width
+	 *            the real width
+	 * @param height
+	 *            the real height
+	 */
+	protected Drawable(VUI vui, double dx, double dy, double width, double height) {
+		this.vui = vui;
+		x = dx;
+		y = dy;
+		this.width = width;
+		this.height = height;
+	}
+
+	/**
+	 * Draw the object if visible and if on screen
+	 * 
+	 * @param graphics
+	 *            The graphics object that must be used to draw
+	 */
+	public void onDraw(Graphics2D graphics) {
+		if (isVisible() && isOnScreen()) {
+			_onDraw(graphics);
+		}
+	}
+
+	/**
+	 * Is the object on screen ?
+	 * 
+	 * @return true if object is on the screen
+	 */
+	private boolean isOnScreen() {
+		return (isPointOnScreen(left(), top()) || isPointOnScreen(left(), bottom())
+				|| isPointOnScreen(right(), bottom()) || isPointOnScreen(right(), top()));
+	}
+
+	/**
+	 * Is a given coordinate on screen
+	 * 
+	 * @param x
+	 *            the horitontal position
+	 * @param y
+	 *            the vertical position
+	 * @return true if the point is on the screen
+	 */
+	private boolean isPointOnScreen(double x, double y) {
+		return x >= 0 && x <= vui.getCanvasWidth() && y >= 0 && y <= vui.getCanvasHeight();
+	}
+
+	/**
+	 * Method that must be overrided to draw
+	 * 
+	 * @param graphics
+	 *            the Graphics2D object
+	 */
+	public abstract void _onDraw(Graphics2D graphics);
+
+	/**
+	 * Method called when the VUI must be refreshed
+	 */
+	public void update() {
+		if (vui != null)
+			vui.updateCanvas();
+	}
+
+	/**
+	 * Set the associated VUI
+	 * 
+	 * @param vectorialUI
+	 */
+	public void setPanel(VUI vectorialUI) {
+		vui = vectorialUI;
+	}
+
+	/**
+	 * Get the top y coordinate
+	 * 
+	 * @return the top y coordinate
+	 */
+	public double top() {
+		if (isFixed())
+			return y - height / 2;
+		else
+			return vui.worldToScreenY(y - height / 2);
+	}
+
+	/**
+	 * Get the left x coordinate
+	 * 
+	 * @return the left x coordinate
+	 */
+	public double left() {
+		if (isFixed())
+			return x - width / 2;
+		else
+			return vui.worldToScreenX(x - width / 2);
+	}
+
+	/**
+	 * Get the bottom y coordinate
+	 * 
+	 * @return the bottom y coordinate
+	 */
+	public double bottom() {
+		if (isFixed())
+			return y + height / 2;
+		else
+			return vui.worldToScreenY(y + height / 2);
+	}
+
+	/**
+	 * Get the right x coordinate
+	 * 
+	 * @return the right x coordinate
+	 */
+	public double right() {
+		if (isFixed())
+			return x + width / 2;
+		else
+			return vui.worldToScreenX(x + width / 2);
+	}
+
+	/**
+	 * Only draw the border of the object
+	 * 
+	 * @return the object for chained methods
+	 */
+	public Drawable setStrokeOnly() {
+		strokeMode = true;
+		update();
+		return this;
+	}
+
+	/**
+	 * 
+	 * @param color
+	 * @return the object for chained methods
+	 */
+	public Drawable setColor(Color color) {
+		if (color == this.color)
+			return this;
+		this.color = color;
+		update();
+		return this;
+	}
+
+	/**
+	 * 
+	 * @param dx
+	 * @param dy
+	 * @return the object for chained methods
+	 */
+	public Drawable move(double dx, double dy) {
+		if (x == dx && y == dy)
+			return this;
+		this.x = dx;
+		this.y = dy;
+		update();
+		return this;
+	}
+
+	/**
+	 * 
+	 * @return the object for chained methods
+	 */
+	public Drawable setFixed() {
+		this.fixed = true;
+		update();
+		return this;
+	}
+
+	/**
+	 * 
+	 * @return the object for chained methods
+	 */
+	public Drawable show() {
+		return this.setVisible(true);
+	}
+
+	/**
+	 * 
+	 * @return
+	 */
+	public Drawable hide() {
+		return this.setVisible(false);
+	}
+
+	/**
+	 * 
+	 * @return
+	 */
+	public boolean isVisible() {
+		return visible;
+	}
+
+	/**
+	 * 
+	 * @param visible
+	 * @return the object for chained methods
+	 */
+	public Drawable setVisible(boolean visible) {
+		this.visible = visible;
+		update();
+		return this;
+	}
+}
diff --git a/src/mas/ui/drawables/DrawableCircle.java b/src/mas/ui/drawables/DrawableCircle.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ba660f3a39bff3e2b40c28bdaa7e4242473b90a
--- /dev/null
+++ b/src/mas/ui/drawables/DrawableCircle.java
@@ -0,0 +1,22 @@
+package mas.ui.drawables;
+
+import java.awt.Graphics2D;
+
+import mas.ui.VUI;
+
+public class DrawableCircle extends Drawable {
+	public DrawableCircle(VUI vui, double dx, double dy, double size) {
+		super(vui, dx, dy, size, size);
+	}
+
+	@Override
+	public void _onDraw(Graphics2D graphics) {
+		graphics.setColor(color);
+		if (strokeMode)
+			graphics.drawOval((int)left(), (int)top(), (int) getRenderedWidth(), (int) getRenderedHeight());
+		else
+			graphics.fillOval((int)left(), (int)top(), (int) getRenderedWidth(), (int) getRenderedHeight());
+	}
+
+
+}
diff --git a/src/mas/ui/drawables/DrawableImage.java b/src/mas/ui/drawables/DrawableImage.java
new file mode 100644
index 0000000000000000000000000000000000000000..aa385926e53d15aec69d45c84b57bee8f0ca24c4
--- /dev/null
+++ b/src/mas/ui/drawables/DrawableImage.java
@@ -0,0 +1,66 @@
+package mas.ui.drawables;
+
+import mas.ui.VUI;
+
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.imageio.ImageIO;
+
+public class DrawableImage extends Drawable {
+
+	private String filename;
+	private BufferedImage image;
+	private static Map<String, BufferedImage> loadedImages = new HashMap<>();
+
+	public DrawableImage(VUI vui, double dx, double dy, String filename) {
+		super(vui, dx, dy, 0, 0);
+		this.setFilename(filename);
+
+	}
+
+	private BufferedImage loadByFilename(String filename) throws IOException {
+		if (!loadedImages.containsKey(filename)) {
+			loadedImages.put(filename, ImageIO.read(new File(filename)));
+		}
+		return loadedImages.get(filename);
+	}
+
+	public void setFilename(String filename) {
+		this.filename = filename;
+		try {
+			this.image = loadByFilename(this.filename);
+		} catch (IOException e) {
+			//Log.error("AMAK", "Can't find/load the file %s", this.filename);
+			e.printStackTrace();
+			try {
+				this.image = loadByFilename("Resources/unavailable.png");
+			} catch (IOException e1) {
+				e1.printStackTrace();
+			}
+		}
+		setWidth(this.image.getWidth());
+		setHeight(this.image.getHeight());
+
+	}
+
+	@Override
+	public void _onDraw(Graphics2D graphics) {
+		AffineTransform identity = new AffineTransform();
+		AffineTransform trans = new AffineTransform();
+		trans.setTransform(identity);
+		trans.translate(left(), top());
+		trans.rotate(getAngle(), getRenderedWidth() / 2, getRenderedHeight() / 2);
+		if (!isFixed())
+			trans.scale(vui.getZoomFactor()*getWidth()/this.image.getWidth(), vui.getZoomFactor()*getHeight()/this.image.getHeight());
+		graphics.drawImage(image, trans, null);
+		
+	}
+
+
+}
diff --git a/src/mas/ui/drawables/DrawableLine.java b/src/mas/ui/drawables/DrawableLine.java
new file mode 100644
index 0000000000000000000000000000000000000000..0b7db864b66bfd2222b0b9dc1afcc3f8bfc6ec35
--- /dev/null
+++ b/src/mas/ui/drawables/DrawableLine.java
@@ -0,0 +1,38 @@
+package mas.ui.drawables;
+
+import mas.ui.VUI;
+
+import java.awt.Graphics2D;
+
+public class DrawableLine extends Drawable {
+
+	private double x2, x1;
+	private double y2, y1;
+
+	public DrawableLine(VUI vui, double dx, double dy, double tx, double ty) {
+		super(vui, 0, 0, 0, 0);
+
+		x1 = dx;
+		y1 = dy;
+		x2 = tx;
+		y2 = ty;
+	}
+
+	@Override
+	public void _onDraw(Graphics2D graphics) {
+		graphics.setColor(color);
+		if (isFixed())
+			graphics.drawLine((int) x1, (int) y1, (int) x2, (int) y2);
+		else
+			graphics.drawLine(vui.worldToScreenX(x1), vui.worldToScreenY(y1), vui.worldToScreenX(x2),
+					vui.worldToScreenY(y2));
+	}
+
+	public void move(double dx, double dy, double tx, double ty) {
+		x1 = dx;
+		y1 = dy;
+		x2 = tx;
+		y2 = ty;
+		update();
+	}
+}
diff --git a/src/mas/ui/drawables/DrawableOval.java b/src/mas/ui/drawables/DrawableOval.java
new file mode 100644
index 0000000000000000000000000000000000000000..856234610492a7001668cf82f7e01420090cdb5a
--- /dev/null
+++ b/src/mas/ui/drawables/DrawableOval.java
@@ -0,0 +1,22 @@
+package mas.ui.drawables;
+
+import java.awt.Graphics2D;
+
+import mas.ui.VUI;
+
+public class DrawableOval extends Drawable {
+	public DrawableOval(VUI vui, double dx, double dy, double width, double height) {
+		super(vui, dx, dy, width, height);
+	}
+
+	@Override
+	public void _onDraw(Graphics2D graphics) {
+		graphics.setColor(color);
+		if (strokeMode)
+			graphics.drawOval((int)left(), (int)top(), (int) getRenderedWidth(), (int) getRenderedHeight());
+		else
+			graphics.fillOval((int)left(), (int)top(), (int) getRenderedWidth(), (int) getRenderedHeight());
+	}
+
+
+}
diff --git a/src/mas/ui/drawables/DrawablePoint.java b/src/mas/ui/drawables/DrawablePoint.java
new file mode 100644
index 0000000000000000000000000000000000000000..55fefe64df0f593426d625c1a86a84e096e91dba
--- /dev/null
+++ b/src/mas/ui/drawables/DrawablePoint.java
@@ -0,0 +1,12 @@
+package mas.ui.drawables;
+
+
+import mas.ui.VUI;
+
+public class DrawablePoint extends DrawableRectangle {
+
+	public DrawablePoint(VUI vui, double dx, double dy) {
+		super(vui, dx, dy, 10, 10);
+	}
+
+}
diff --git a/src/mas/ui/drawables/DrawableRectangle.java b/src/mas/ui/drawables/DrawableRectangle.java
new file mode 100644
index 0000000000000000000000000000000000000000..ff4143e277ba4788fda4cdc564260b0ea917e0a9
--- /dev/null
+++ b/src/mas/ui/drawables/DrawableRectangle.java
@@ -0,0 +1,21 @@
+package mas.ui.drawables;
+
+import mas.ui.VUI;
+
+import java.awt.Graphics2D;
+
+public class DrawableRectangle extends Drawable {
+	public DrawableRectangle(VUI vui, double dx, double dy, double width, double height) {
+		super(vui, dx, dy, width, height);
+	}
+
+	@Override
+	public void _onDraw(Graphics2D graphics) {
+		graphics.setColor(color);
+		if (strokeMode)
+			graphics.drawRect((int)left(), (int)top(), (int)getRenderedWidth(), (int)getRenderedHeight());
+		else
+			graphics.fillRect((int)left(), (int)top(), (int)getRenderedWidth(), (int)getRenderedHeight());
+	}
+
+}
diff --git a/src/mas/ui/drawables/DrawableString.java b/src/mas/ui/drawables/DrawableString.java
new file mode 100644
index 0000000000000000000000000000000000000000..2a3eb3842dc61da3e75acab676996fa23276b1c1
--- /dev/null
+++ b/src/mas/ui/drawables/DrawableString.java
@@ -0,0 +1,26 @@
+package mas.ui.drawables;
+
+import mas.ui.VUI;
+
+import java.awt.Graphics2D;
+
+public class DrawableString extends Drawable {
+	private String text;
+
+	public DrawableString(VUI vui, double dx, double dy, String text) {
+		super(vui, dx, dy, 1, 1);
+		this.text = text;
+	}
+
+	@Override
+	public void _onDraw(Graphics2D graphics) {
+		graphics.setColor(color);
+		graphics.drawString(text, (int)left(), (int)top());
+	}
+
+	public void setText(String text) {
+		this.text = text;
+	}
+
+
+}