diff --git a/src/main/java/lab/BulletAnimated.java b/src/main/java/lab/BulletAnimated.java
index 294ad2224d36c995a397101beddad77507592ede..1546845bbe341e25d97ef031304a2b437a3ffafb 100644
--- a/src/main/java/lab/BulletAnimated.java
+++ b/src/main/java/lab/BulletAnimated.java
@@ -5,9 +5,8 @@ import javafx.geometry.Rectangle2D;
 import javafx.scene.canvas.GraphicsContext;
 import javafx.scene.image.Image;
 
-public class BulletAnimated {
+public class BulletAnimated extends WorldEntity implements Collisionable{
 
-	private Point2D position;
 	private Point2D start;
 	private Point2D speed;
 	private Point2D initialSpeed;
@@ -22,7 +21,6 @@ public class BulletAnimated {
 	private double dragCoefficient = 0.47;
 	
 	private Image image;
-	private World world;
 	private Cannon cannon;
 
 	public BulletAnimated(World world, Cannon cannon) {
@@ -30,27 +28,20 @@ public class BulletAnimated {
 	}
 
 	public BulletAnimated(World world, Cannon cannon, Point2D start, Point2D speed, double size) {
+		super(start, world);
 		this.start = start;
-		this.position = this.start;
 		this.initialSpeed = speed;
 		this.speed = speed;
 		this.size = size;
-		this.world = world;
 		this.cannon = cannon;
 		image = new Image(getClass().getResourceAsStream("fireball-transparent.gif"), size, size,
 				true, true);
 	}
 
-	public void draw(GraphicsContext gc) {
-		gc.save();
-		Point2D canvasPosition = world.getCanvasPoint(position);
-		gc.drawImage(image, canvasPosition.getX(), canvasPosition.getY());
-		gc.restore();
-	}
-
+	@Override
 	public void simulate(double deltaT) {
 		double timeStep = deltaT * 1000;
-		if (accelerate && start.distance(position) < cannonLength) {
+		if (accelerate && start.distance(getPosition()) < cannonLength) {
 			double cannonAngle = cannon.getAngle(); 
 			speed = speed
 					.add(new Point2D(Math.cos(cannonAngle) * strenghtOfCannon, Math.sin(cannonAngle) * strenghtOfCannon)
@@ -65,10 +56,10 @@ public class BulletAnimated {
 			speed = speed.add(acceleration.multiply(timeStep / 1000));
 		}
 		if (!hitToGround) {
-			position = position.add(speed);
-			if (!accelerate && position.getY() <= size / 2) {
+			setPosition(getPosition().add(speed));
+			if (!accelerate && getPosition().getY() <= size / 2) {
 				hitToGround = true;
-				position = new Point2D(position.getX(), size / 2);
+				setPosition(new Point2D(getPosition().getX(), size / 2));
 			}
 		} else {
 			reload();
@@ -78,7 +69,12 @@ public class BulletAnimated {
 	}
 
 	public Rectangle2D getBoundingBox() {
-		return new Rectangle2D(position.getX(), position.getY(), size, size);
+		return new Rectangle2D(getPosition().getX(), getPosition().getY(), size, size);
+	}
+	
+	@Override
+	public void hitBy(Collisionable other) {
+		reload();
 	}
 	
 	public boolean overlaps(Dragon dragon) {
@@ -86,10 +82,15 @@ public class BulletAnimated {
 	}
 	
 	public void reload() {
-		position = start;
+		setPosition(start);
 		speed = initialSpeed;
 		hitToGround = false;
 		accelerate = true;
 	}
-	
+
+	@Override
+	protected void drawInternal(GraphicsContext gc) {
+		Point2D canvasPosition = getWorld().getCanvasPoint(getPosition());
+		gc.drawImage(image, canvasPosition.getX(), canvasPosition.getY());
+	}
 }
diff --git a/src/main/java/lab/Cannon.java b/src/main/java/lab/Cannon.java
index b46745dc0779c5152639f0c4c9815c34f80d56fa..296ce0e5a4e1bc99b4fe587b2571d1d3ca8591ed 100644
--- a/src/main/java/lab/Cannon.java
+++ b/src/main/java/lab/Cannon.java
@@ -5,21 +5,15 @@ import javafx.scene.canvas.GraphicsContext;
 import javafx.scene.paint.Color;
 import javafx.scene.transform.Affine;
 
-public class Cannon {
+public class Cannon extends WorldEntity{
 
 	private int direction=-1;
 	private double angle = 0;
-	private Point2D position;
 	private Point2D size;
-	private World world;
 	
 	
-	 
-
 	public Cannon(World world, Point2D position, Point2D size) {
-		super();
-		this.world = world;
-		this.position = position;
+		super(position, world);
 		this.size = size;
 	}
 
@@ -30,9 +24,14 @@ public class Cannon {
 		}
 	}
 	
-	public void draw(GraphicsContext gc) {
-		gc.save();
-		Point2D worldPosition = world.getCanvasPoint(position);
+	
+	public double getAngle() {
+		return (angle * -1) / 180 * Math.PI;
+	}
+
+	@Override
+	protected void drawInternal(GraphicsContext gc) {
+		Point2D worldPosition = getWorld().getCanvasPoint(getPosition());
 		gc.setFill(Color.BROWN);
 		gc.fillRect(worldPosition.getX()-10, worldPosition.getY()+size.getY(), size.getX()+20, size.getY()/2);
 		gc.fillOval(worldPosition.getX()-20, worldPosition.getY()+size.getY()/2, 40, 40);
@@ -40,10 +39,5 @@ public class Cannon {
 		gc.setTransform(new Affine(Affine.rotate(angle, worldPosition.getX(), worldPosition.getY()+size.getY()/2)));
 		gc.setFill(Color.BLACK);
 		gc.fillRect(worldPosition.getX(), worldPosition.getY(), size.getX(), size.getY());
-		gc.restore();
-	}
-
-	public double getAngle() {
-		return (angle * -1) / 180 * Math.PI;
 	}
 }
diff --git a/src/main/java/lab/Collisionable.java b/src/main/java/lab/Collisionable.java
new file mode 100644
index 0000000000000000000000000000000000000000..e95da10a5e4c9bfbd70920d3233ba7e77ab5171b
--- /dev/null
+++ b/src/main/java/lab/Collisionable.java
@@ -0,0 +1,15 @@
+package lab;
+
+import javafx.geometry.Rectangle2D;
+
+public interface Collisionable {
+	
+	void hitBy(Collisionable other);
+	
+	default boolean intersects(Collisionable other) {
+		return getBoundingBox().intersects(other.getBoundingBox());
+	}
+	
+	Rectangle2D getBoundingBox();
+
+}
diff --git a/src/main/java/lab/Dragon.java b/src/main/java/lab/Dragon.java
index 216628afbd03d95d4896abc8b5175efcb25709c8..1945c379ed9dd831e8ac7ce22a71c102aed0255c 100644
--- a/src/main/java/lab/Dragon.java
+++ b/src/main/java/lab/Dragon.java
@@ -4,49 +4,48 @@ import javafx.geometry.Point2D;
 import javafx.geometry.Rectangle2D;
 import javafx.scene.canvas.GraphicsContext;
 
-public class Dragon {
+public class Dragon extends WorldEntity implements Collisionable {
 	
-	private Point2D position;
 	
 	private Point2D speed;
 	
-	private final World world;
 		
 	private final double size = 45;
 
 	public Dragon(World world, Point2D position, Point2D speed) {
-		super();
-		this.world = world;
-		this.position = position;
+		super(position, world);
 		this.speed = speed;
 	}
 
 	
-	public void draw(GraphicsContext gc) {
-		Point2D canvasPosition = world.getCanvasPoint(position);
+	protected void drawInternal(GraphicsContext gc) {
+		Point2D canvasPosition = getWorld().getCanvasPoint(getPosition());
 		gc.drawImage(Constants.DRAGON_IMAGE, canvasPosition.getX(), canvasPosition.getY(), size, size);
 	}
 
 
 	public void simulate(double timeDelta) {
 		double timeDeltaS = timeDelta;
-		double newX = (position.getX() + speed.getX() * timeDeltaS + world.getWidth()) % world.getWidth(); 
-		double newY = (position.getY() + speed.getY() * timeDeltaS + world.getHeight()) % world.getHeight();
-		position = new Point2D(newX, newY);
+		double newX = (getPosition().getX() + speed.getX() * timeDeltaS + getWorld().getWidth()) % getWorld().getWidth(); 
+		double newY = (getPosition().getY() + speed.getY() * timeDeltaS + getWorld().getHeight()) % getWorld().getHeight();
+		setPosition(new Point2D(newX, newY));
 	}
 
-
+	@Override
 	public Rectangle2D getBoundingBox() {
-		return new Rectangle2D(position.getX(), position.getY(), size, size);
-	}
-
-
-	public void hit() {
-		speed = speed.multiply(-1.);
+		return new Rectangle2D(getPosition().getX(), getPosition().getY(), size, size);
 	}
-
 	
+	@Override
+	public void hitBy(Collisionable other) {
+		if (!(other instanceof Dragon)) {
+			hit();
+		}
+	}
 	
 	
+	public void hit() {
+		speed = speed.multiply(-1.);
+	}
 	
 }
diff --git a/src/main/java/lab/DrawableSimulable.java b/src/main/java/lab/DrawableSimulable.java
new file mode 100644
index 0000000000000000000000000000000000000000..f0925cd6285efe7a50e2d8a49f27a0b2544735d6
--- /dev/null
+++ b/src/main/java/lab/DrawableSimulable.java
@@ -0,0 +1,8 @@
+package lab;
+
+import javafx.scene.canvas.GraphicsContext;
+
+public interface DrawableSimulable {
+	void draw(GraphicsContext gc);
+	void simulate(double deltaT);
+}
diff --git a/src/main/java/lab/World.java b/src/main/java/lab/World.java
index ce631f92042437d374ab6c311c2778450a88858c..9baa756e8e4527300d8cf49b806b01794c6c116b 100644
--- a/src/main/java/lab/World.java
+++ b/src/main/java/lab/World.java
@@ -7,19 +7,17 @@ import javafx.scene.canvas.GraphicsContext;
 public class World {
 	private double width;
 	private double height;
-	private BulletAnimated bulletAnimatted;
-	private Cannon cannon;
-	private Dragon[] dragons;
+	private DrawableSimulable[] entities;
 
 	public World(double width, double height) {
 		super();
 		this.width = width;
 		this.height = height;
-		cannon = new Cannon(this, new Point2D(50, 50), new Point2D(100, 20));
-		bulletAnimatted = new BulletAnimated(this, cannon, new Point2D(30, 60), new Point2D(0, 0), 40);
-		dragons = new Dragon[] { new Dragon(this, new Point2D(50, 200), new Point2D(100, 5)),
+		Cannon cannon = new Cannon(this, new Point2D(50, 50), new Point2D(100, 20));
+		BulletAnimated bullet = new BulletAnimated(this, cannon, new Point2D(30, 60), new Point2D(0, 0), 40);
+		entities = new DrawableSimulable[] {cannon, bullet, new Dragon(this, new Point2D(50, 200), new Point2D(100, 5)),
 				new Dragon(this, new Point2D(50, 230), new Point2D(60, 5)),
-				new Dragon(this, new Point2D(50, 270), new Point2D(-50, 20)) };
+				new Dragon(this, new Point2D(50, 270), new Point2D(-50, 20))};
 	}
 
 	public Point2D getCanvasPoint(Point2D worldPoint) {
@@ -29,22 +27,26 @@ public class World {
 	public void draw(Canvas canvas) {
 		GraphicsContext gc = canvas.getGraphicsContext2D();
 		gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
-		cannon.draw(gc);
-		bulletAnimatted.draw(gc);
-		for(Dragon dragon: dragons) {
-			dragon.draw(gc);
+		for(DrawableSimulable entity: entities) {
+			entity.draw(gc);
 		}
 	}
 
 	public void simulate(double timeDelta) {
-		bulletAnimatted.simulate(timeDelta);
-		cannon.simulate(timeDelta);
-		for(Dragon dragon: dragons) {
-			if (bulletAnimatted.overlaps(dragon)) {
-				dragon.hit();
-				bulletAnimatted.reload();
+		for(DrawableSimulable entity: entities) {
+			entity.simulate(timeDelta);
+			if (entity instanceof Collisionable) {
+				Collisionable col1 = (Collisionable) entity;
+				for (DrawableSimulable entity2: entities) {
+					if (entity2 != entity && entity2 instanceof Collisionable) {
+						Collisionable col2 = (Collisionable) entity2;
+						if (col1.intersects(col2)) {
+							col1.hitBy(col2);
+							col2.hitBy(col1);
+						}
+					}
+				}
 			}
-			dragon.simulate(timeDelta);
 		}
 	}
 
diff --git a/src/main/java/lab/WorldEntity.java b/src/main/java/lab/WorldEntity.java
new file mode 100644
index 0000000000000000000000000000000000000000..040b621b150d0678dd4595bbcf03ce36e1619120
--- /dev/null
+++ b/src/main/java/lab/WorldEntity.java
@@ -0,0 +1,41 @@
+package lab;
+
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+
+public abstract class WorldEntity implements DrawableSimulable{
+	
+	private Point2D position;
+	
+	private final World world;
+
+	public WorldEntity(Point2D position, World world) {
+		this.position = position;
+		this.world = world;
+	}
+	
+	@Override
+	public void draw(GraphicsContext gc) {
+		gc.save();
+		drawInternal(gc);
+		gc.restore();
+	}
+	
+	protected abstract void drawInternal(GraphicsContext gc);
+
+	protected Point2D getPosition() {
+		return position;
+	}
+	
+	
+	protected void setPosition(Point2D position) {
+		this.position = position;
+	}
+
+	protected World getWorld() {
+		return world;
+	}
+	
+	
+	
+}