diff --git a/src/main/java/engine/physic/PhysicEngine.java b/src/main/java/engine/physic/PhysicEngine.java
index 63ee86879ed6fc122986df2415e6fa05ff072f03..2341227beab1c1a8852017fa385672ae6e6dcc7b 100644
--- a/src/main/java/engine/physic/PhysicEngine.java
+++ b/src/main/java/engine/physic/PhysicEngine.java
@@ -22,7 +22,7 @@ public class PhysicEngine implements Engine {
             Coordinates2D previousPosition = pongObjectEntityHashMap.get(pongObject).getPosition();
             pongObjectEntityHashMap.get(pongObject).updatePosition();// Updating of the associated movable position
             if(pongObject.getName().equals("Ball")){
-                System.out.println("Ball position: " + pongObjectEntityHashMap.get(pongObject).getPosition().getX() + " ; " + pongObjectEntityHashMap.get(pongObject).getPosition().getY());
+                //System.out.println("Ball position: " + pongObjectEntityHashMap.get(pongObject).getPosition().getX() + " ; " + pongObjectEntityHashMap.get(pongObject).getPosition().getY());
                 //System.out.println("Ball init position: " + pongObjectEntityHashMap.get(pongObject).getInitPosition());
                 for (PongObject po2: pongObjectEntityHashMap.keySet()
                 ) {
@@ -34,12 +34,13 @@ public class PhysicEngine implements Engine {
                             Kernel.isCollision = true;
                             System.out.println("Collision " + i);
                             pongObjectEntityHashMap.get(pongObject).setPosition(previousPosition);
-                            if(i % 2 == 0){
-                                pongObjectEntityHashMap.get(pongObject).getSpeed().add(new Coordinates2D(1, 1));
+                            if(i % 10 == 0){
+                                pongObjectEntityHashMap.get(pongObject).getSpeed().mul(2);
                             }
-
-                            pongObjectEntityHashMap.get(pongObject).getSpeed().mul(-1);
-                            //TODO: implements pong object collision physics
+                            pongObject.setSpeed(pongObjectEntityHashMap.get(pongObject).getSpeed());
+                            //pongObjectEntityHashMap.get(pongObject).getSpeed().mul(-1);
+                            pongObject.updateSpeed(po2.doItHitHalf(pongObject.getPosition()), po2.isLeftRacket());
+                            pongObjectEntityHashMap.get(pongObject).setSpeed(pongObject.getSpeed());
 
                             pongObjectEntityHashMap.get(pongObject).updatePosition();
                         }
diff --git a/src/main/java/pong/PongApp.java b/src/main/java/pong/PongApp.java
index 06a0ea2bdeef0b27ed9a3dad484e17fcddf4f16f..c542ca948e94ad9595260d97f7822ff73fa471bb 100644
--- a/src/main/java/pong/PongApp.java
+++ b/src/main/java/pong/PongApp.java
@@ -35,10 +35,10 @@ public class PongApp {
         int racketHeight = 120;
         int ballWidth = 32;
 
-        PongRacket leftRacket = new PongRacket("Left racket", "src/main/resources/pong/raquette.png", new Coordinates2D(widthDiff + 5, height/2 - racketHeight/2), racketWidth, racketHeight);
+        PongRacket leftRacket = new PongRacket("Left racket", "src/main/resources/pong/raquette.png", new Coordinates2D(widthDiff + 5, height/2 - racketHeight/2), racketWidth, racketHeight, true);
         components.add(leftRacket);
 
-        PongRacket rightRacket = new PongRacket("Right racket", "src/main/resources/pong/raquette.png", new Coordinates2D(rectWidth + widthDiff - 5 - racketWidth, height/2 - racketHeight/2), racketWidth, racketHeight);
+        PongRacket rightRacket = new PongRacket("Right racket", "src/main/resources/pong/raquette.png", new Coordinates2D(rectWidth + widthDiff - 5 - racketWidth, height/2 - racketHeight/2), racketWidth, racketHeight, false);
         components.add(rightRacket);
 
         PongBall pongBall = new PongBall("Ball", "src/main/resources/pong/ball.png", new Coordinates2D(width/2, height/2), ballWidth, ballWidth);
diff --git a/src/main/java/pong/PongBall.java b/src/main/java/pong/PongBall.java
index 12f7ab5bfee3f9efce05e39fd2622fe727262428..fd7bcbe0369bfe345440ccaef2597cef4a00838e 100644
--- a/src/main/java/pong/PongBall.java
+++ b/src/main/java/pong/PongBall.java
@@ -10,6 +10,8 @@ public class PongBall implements PongObject {
     private final int width;
     private final int height;
     private Coordinates2D position;
+
+    private Coordinates2D speed;
     private Coordinates2D initPosition;
     private final Image image;
 
@@ -27,6 +29,11 @@ public class PongBall implements PongObject {
         return this.position;
     }
 
+    @Override
+    public Coordinates2D getSpeed() {
+        return this.speed;
+    }
+
 
     @Override
     public Image getImage() {
@@ -53,6 +60,50 @@ public class PongBall implements PongObject {
         this.position = position;
     }
 
+    @Override
+    public void setSpeed(Coordinates2D speed) {
+        this.speed = speed;
+    }
+
+    /**
+     * Update the speed of the ball when it hits a paddle.
+     * If the ball hits the upper half of the paddle, the ball will go up
+     * If the ball hits the lower half of the paddle, the ball will go down
+     * @param isUpperHalf
+     */
+    @Override
+    public void updateSpeed(boolean isUpperHalf, boolean isLeftRacket){
+        System.out.println("updateSpeed");
+        if(!isLeftRacket){
+            System.out.println("isLeftRacket");
+            if(isUpperHalf){
+                if(this.speed.getY() > 0){
+                    this.speed.setY(this.speed.getY() * -1);
+                }
+            }else{
+                if (this.speed.getY() < 0){
+                    this.speed.setY(this.speed.getY() * -1);
+                }
+            }
+            if (this.speed.getX() > 0){
+                this.speed.setX(this.speed.getX() * -1);
+            }
+        } else {
+            if(isUpperHalf){
+                if(this.speed.getY() > 0){
+                    this.speed.setY(this.speed.getY() * -1);
+                }
+            }else{
+                if (this.speed.getY() < 0){
+                    this.speed.setY(this.speed.getY() * -1);
+                }
+            }
+            if (this.speed.getX() < 0){
+                this.speed.setX(this.speed.getX() * -1);
+            }
+        }
+    }
+
     @Override
     public String getName() {
         return name;
@@ -62,4 +113,14 @@ public class PongBall implements PongObject {
     public Coordinates2D getInitPosition() {
         return this.initPosition;
     }
+
+    @Override
+    public boolean doItHitHalf(Coordinates2D ballPosition) {
+        return false;
+    }
+
+    @Override
+    public boolean isLeftRacket() {
+        return false;
+    }
 }
diff --git a/src/main/java/pong/PongObject.java b/src/main/java/pong/PongObject.java
index b40f5bea2af6a2d08781a0a811301a6eeb42d386..77a7fac81c358b1fbe828abff552c320380508ca 100644
--- a/src/main/java/pong/PongObject.java
+++ b/src/main/java/pong/PongObject.java
@@ -6,13 +6,25 @@ import java.awt.*;
 
 public interface PongObject {
     public Coordinates2D getPosition();
+
+    public Coordinates2D getSpeed();
     public Image getImage();
     public int getWidth();
     public int getHeight();
     public int getResistance();
     public void setPosition(Coordinates2D position);
 
+    public void setSpeed(Coordinates2D speed);
+
+    void updateSpeed(boolean isUpperHalf, boolean isLeftRacket);
+
+
     public String getName();
 
     Coordinates2D getInitPosition();
+
+
+    boolean doItHitHalf(Coordinates2D ballPosition);
+
+    boolean isLeftRacket();
 }
diff --git a/src/main/java/pong/PongRacket.java b/src/main/java/pong/PongRacket.java
index 59009daa706f6649e6a5aae49d7b2ddf803c669f..3d94fdb3607195d451dbdf1a1c746d335ff7bb40 100644
--- a/src/main/java/pong/PongRacket.java
+++ b/src/main/java/pong/PongRacket.java
@@ -12,13 +12,18 @@ public class PongRacket implements PongObject {
     private Coordinates2D position;
     private final Coordinates2D initPosition;
     private final Image image;
-    public PongRacket(String name, String imagePath, Coordinates2D position, int width, int height) {
+    private Coordinates2D speed;
+
+    private boolean isLeftRacket;
+
+    public PongRacket(String name, String imagePath, Coordinates2D position, int width, int height, boolean isLeftRacket) {
         this.name = name;
         this.width = width;
         this.height = height;
         this.image = Toolkit.getDefaultToolkit().getImage(imagePath);
         this.position = position;
         this.initPosition = position;
+        this.isLeftRacket = isLeftRacket;
     }
 
     @Override
@@ -26,6 +31,11 @@ public class PongRacket implements PongObject {
         return position;
     }
 
+    @Override
+    public Coordinates2D getSpeed() {
+        return this.speed;
+    }
+
     @Override
     public Image getImage() {
         return this.image;
@@ -51,6 +61,16 @@ public class PongRacket implements PongObject {
         this.position = position;
     }
 
+    @Override
+    public void setSpeed(Coordinates2D speed) {
+        this.speed = speed;
+    }
+
+    @Override
+    public void updateSpeed(boolean isUpperHalf, boolean isLeftRacket) {
+
+    }
+
     @Override
     public String getName() {
         return name;
@@ -60,4 +80,18 @@ public class PongRacket implements PongObject {
     public Coordinates2D getInitPosition() {
         return initPosition;
     }
+
+    /**
+     * @param ballPosition
+     * @return true if the ball hit the upper half of the racket
+     */
+    @Override
+    public boolean doItHitHalf(Coordinates2D ballPosition) {
+        return ballPosition.getY() < this.position.getY() + this.height / 2;
+    }
+
+    @Override
+    public boolean isLeftRacket() {
+        return isLeftRacket;
+    }
 }
diff --git a/src/test/java/engine/PongObjectTest.java b/src/test/java/engine/PongObjectTest.java
deleted file mode 100644
index 4f41b0eed8faf2183e76a4bd163f9a4694b81781..0000000000000000000000000000000000000000
--- a/src/test/java/engine/PongObjectTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package engine;
-
-import engine.physic.Coordinates2D;
-import engine.physic.Movable;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-class PongObjectTest {
-    @Test
-    public void testPositionUpdating() {
-        Movable newMovable = new Movable(1, new Coordinates2D(0, 0), new Coordinates2D(0, 0), new Coordinates2D(0, 0), 0);
-        //With constant acceleration (not (0, 0))
-        int delta = 1;
-        while(delta <= 5){
-            if(delta % 2 == 0) {
-                newMovable.updatePosition(new Coordinates2D(1, 1));
-                //System.out.println("Position: " + newHero.getPosition().getRow() + ", " + newHero.getPosition().getCol());
-            }
-            delta++;
-        }
-        //The position supposed to be (3, 3)
-        assertEquals(3, newMovable.getPosition().getX());
-        assertEquals(3, newMovable.getPosition().getY());
-
-        //With variable acceleration (croissant)
-        delta = 1;
-        while(delta <= 5){
-            if(delta % 2 == 0) {
-                newMovable.updatePosition(new Coordinates2D(delta, delta));
-                //System.out.println("Position: " + newHero.getPosition().getRow() + ", " + newHero.getPosition().getCol());
-            }
-            delta++;
-        }
-        //The position supposed to be (15, 15)
-        assertEquals( 15, newMovable.getPosition().getX());
-        assertEquals( 15, newMovable.getPosition().getY());
-
-        //With variable acceleration (decroissant)
-        delta = 5;
-        while(delta >= 1){
-            if(delta % 2 == 0) {
-                newMovable.updatePosition(new Coordinates2D(delta, delta));
-                //System.out.println("Position: " + newHero.getPosition().getRow() + ", " + newHero.getPosition().getCol());
-            }
-            delta--;
-        }
-        //The position supposed to be (41, 41)
-        assertEquals( 41, newMovable.getPosition().getX());
-        assertEquals( 41, newMovable.getPosition().getY());
-
-        //With negative acceleration
-        delta = 1;
-        while(delta <= 5){
-            if(delta % 2 == 0) {
-                newMovable.updatePosition(new Coordinates2D(-delta, -delta));
-                //System.out.println("Position: " + newHero.getPosition().getRow() + ", " + newHero.getPosition().getCol());
-            }
-            delta++;
-        }
-        //The position supposed to be (61, 61)
-        assertEquals( 61, newMovable.getPosition().getX());
-        assertEquals( 61, newMovable.getPosition().getY());
-
-        //La vitesse actuelle est un vecteur (8, 8)
-
-        // Test pour vérifier si la vitesse est constante quand l'accélération est nulle
-        delta = 1;
-        while (delta <= 5){
-            if (delta % 2 == 0){
-                newMovable.updatePosition(new Coordinates2D(0, 0));
-            }
-            delta++;
-        }
-        assertEquals(8,newMovable.getSpeed().getX());
-        assertEquals(8,newMovable.getSpeed().getY());
-
-        assertEquals(77,newMovable.getPosition().getY()); // La position est censée être (77, 77)
-        assertEquals(77,newMovable.getPosition().getX());
-
-    }
-
-    @Test
-    public void testHalt(){
-        Movable newMovable = new Movable(1, new Coordinates2D(0, 0), new Coordinates2D(0, 0), new Coordinates2D(0, 0), 0);
-        int delta = 1;
-        newMovable.updatePosition(new Coordinates2D(1, 1));
-        while(delta <= 5){
-            if(delta % 2 == 0) {
-                if(delta == 2){
-                    newMovable.halt(); //With a null speed, the position is not modified
-                }
-                newMovable.updatePosition(new Coordinates2D(0, 0)); // Without acceleration the speed is not modified but the position is
-                //System.out.println("Position: " + newHero.getPosition().getRow() + ", " + newHero.getPosition().getCol());
-            }
-            delta++;
-        }
-        //The position supposed to be (1, 1) because the hero stopped at (1, 1)
-        assertEquals( 3, newMovable.getPosition().getX());
-        assertEquals( 3, newMovable.getPosition().getY());
-    }
-
-    @Test
-    public void testGraphiqueInterface(){
-
-    }
-
-}
\ No newline at end of file
diff --git a/src/test/java/pong/PongBallTest.java b/src/test/java/pong/PongBallTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..805ca0b9764807cf9a3c4f54a05d7740170d4152
--- /dev/null
+++ b/src/test/java/pong/PongBallTest.java
@@ -0,0 +1,27 @@
+package pong;
+
+import engine.physic.Coordinates2D;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class PongBallTest {
+    /**
+     * Test if the speed of the ball is updated correctly when the ball hits the upper half of the paddle
+     * If we hit the upper half of the paddle, the ball should go up (-x, -y) and
+     * if we hit the lower half of the paddle, the ball should go down (-x, y)
+     */
+    @Test
+    void testUpdateSpeedUpperHalfHit() {
+        PongBall pongBall = new PongBall("ball", "src/main/resources/ball.png", new Coordinates2D(0, 0), 10, 10);
+        pongBall.setSpeed(new Coordinates2D(1, 1));
+        pongBall.updateSpeed(true, true);
+        assertEquals(-1, pongBall.getSpeed().getY());
+        assertEquals(-1 , pongBall.getSpeed().getX());
+
+        pongBall.setSpeed(new Coordinates2D(1, -1));
+        pongBall.updateSpeed(false, true);
+        assertEquals(-1, pongBall.getSpeed().getX());
+        assertEquals(1 , pongBall.getSpeed().getY());
+    }
+}
\ No newline at end of file