diff --git a/src/main/java/lab/DrawingThread.java b/src/main/java/lab/DrawingThread.java
index 1243331c3822cf37a2932e9e8eeb8f336e3de58d..a53ad11bc787100d9ee9201b9edd4e831e80dd54 100644
--- a/src/main/java/lab/DrawingThread.java
+++ b/src/main/java/lab/DrawingThread.java
@@ -8,11 +8,14 @@ public class DrawingThread extends AnimationTimer {
 
 	private final Canvas canvas;
 	private final GraphicsContext gc;
+	private Level level;
+	private long lastTime;
 
 	public DrawingThread(Canvas canvas) {
 		this.canvas = canvas;
 		this.gc = canvas.getGraphicsContext2D();
-		
+		this.level = new Level(canvas.getWidth(), canvas.getHeight());
+		lastTime = System.nanoTime();
 	}
 
 	/**
@@ -20,11 +23,9 @@ public class DrawingThread extends AnimationTimer {
 	 */
 	@Override
 	public void handle(long now) {
-		// put your code here
-//		gc.setFill(Color.AQUA);
-//		gc.setStroke(Color.BLACK);
-//		gc.fillOval(10, 10, 20, 20);
-
+		level.draw(gc);
+		level.simulate(now - lastTime);
+		lastTime = now;
 	}
 
 }
diff --git a/src/main/java/lab/Level.java b/src/main/java/lab/Level.java
new file mode 100644
index 0000000000000000000000000000000000000000..819c89f6ca062846c412c1764d2dfbfa959db727
--- /dev/null
+++ b/src/main/java/lab/Level.java
@@ -0,0 +1,39 @@
+package lab;
+
+import javafx.geometry.Dimension2D;
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+
+public class Level {
+
+	private NicerObstacle nicerObstacle;
+	private Obstacle obstacle1;
+	private Obstacle obstacle2;
+	private Player player;
+	private double width;
+	private double height;
+
+	public Level(double width, double height) {
+		this.width = width;
+		this.height = height;
+		nicerObstacle = new NicerObstacle(this, new Point2D(20, 150));
+		obstacle1 = new Obstacle(this, new Point2D(300, 200), new Dimension2D(80, 40));
+		obstacle2 = new Obstacle(this);
+		player = new Player(this, new Point2D(20, 250), new Point2D(0.5, -0.1));
+	}
+
+	public void draw(GraphicsContext gc) {
+		gc.setFill(Color.WHITE);
+		gc.clearRect(0, 0, width, height);
+		nicerObstacle.draw(gc);
+		obstacle1.draw(gc);
+		obstacle2.draw(gc);
+		player.draw(gc);
+	}
+
+	public void simulate(double delay) {
+		player.simulate(0);
+	}
+
+}
diff --git a/src/main/java/lab/NicerObstacle.java b/src/main/java/lab/NicerObstacle.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd3988696dd593f8f75148de0e3ee62687abd1a7
--- /dev/null
+++ b/src/main/java/lab/NicerObstacle.java
@@ -0,0 +1,27 @@
+package lab;
+
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.image.Image;
+
+public class NicerObstacle {
+
+	private Level level;
+	private Image image;
+	private Point2D position;
+
+	public NicerObstacle(Level level, Point2D position) {
+		this.level = level;
+		this.position = position;
+		image = new Image(getClass().getResourceAsStream("spike.gif"));
+	}
+
+	public void draw(GraphicsContext gc) {
+		gc.drawImage(image, position.getX(), position.getY());
+	}
+
+	public void simulate(double delay) {
+		
+	}
+
+}
diff --git a/src/main/java/lab/Obstacle.java b/src/main/java/lab/Obstacle.java
new file mode 100644
index 0000000000000000000000000000000000000000..0c0fe1dec4cff3b459b58f263f9f42e729bec719
--- /dev/null
+++ b/src/main/java/lab/Obstacle.java
@@ -0,0 +1,38 @@
+package lab;
+
+import javafx.geometry.Dimension2D;
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+
+public class Obstacle {
+
+	private Level level;
+	private Point2D position;
+	private Dimension2D size;
+
+	public Obstacle(Level level) {
+		this(level, new Point2D(200, 100), new Dimension2D(30, 20));
+	}
+
+	public Obstacle(Level level, Point2D position, Dimension2D size) {
+		this.level = level;
+		this.position = position;
+		this.size = size;
+	}
+
+	public void draw(GraphicsContext gc) {
+		gc.save();
+		gc.setFill(Color.BLUEVIOLET);
+		gc.setStroke(Color.RED);
+		gc.setLineWidth(3);
+		gc.fillRect(position.getX(), position.getY(), size.getWidth(), size.getHeight());
+		gc.strokeRect(position.getX(), position.getY(), size.getWidth(), size.getHeight());
+		gc.restore();
+	}
+
+	public void simulate(double delay) {
+
+	}
+
+}
diff --git a/src/main/java/lab/Player.java b/src/main/java/lab/Player.java
new file mode 100644
index 0000000000000000000000000000000000000000..aa8e6203feefa4de5ce65e4a9935dc6b8d4c2f23
--- /dev/null
+++ b/src/main/java/lab/Player.java
@@ -0,0 +1,43 @@
+package lab;
+
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+import javafx.scene.transform.Affine;
+import javafx.scene.transform.Rotate;
+
+public class Player {
+	private Level level;
+	private Point2D position;
+	private Point2D speed;
+
+	public Player(Level level, Point2D position, Point2D speed) {
+		this.level = level;
+		this.position = position;
+		this.speed = speed;
+	}
+
+	public void draw(GraphicsContext gc) {
+		gc.save();
+		Point2D center = position.add(10, 25);
+		double angle = speed.angle(1, 0);
+		if (speed.getY() < 0) {
+			angle = -angle;
+		}
+		Rotate rotateMatrix = Affine.rotate(angle, center.getX(), center.getY());
+		gc.setTransform(new Affine(rotateMatrix));
+		gc.setFill(Color.AQUA);
+		gc.setStroke(Color.GREEN);
+		gc.setLineWidth(5);
+		gc.fillRect(center.getX(), center.getY(), 50, 1);
+		gc.fillRoundRect(position.getX(), position.getY(), 20, 50, 20, 20);
+		gc.strokeRoundRect(position.getX(), position.getY(), 20, 50, 20, 20);
+		gc.restore();
+	}
+
+	public void simulate(double delay) {
+		position = position.add(speed);
+		speed = speed.multiply(0.998);
+	}
+
+}
diff --git a/src/main/resources/lab/spike.gif b/src/main/resources/lab/spike.gif
new file mode 100644
index 0000000000000000000000000000000000000000..0d7d4186d65da5d8534d7ae3394b777edd5518b9
Binary files /dev/null and b/src/main/resources/lab/spike.gif differ