diff --git a/main.c b/main.c
index 4919f34..4b5c843 100644
--- a/main.c
+++ b/main.c
@@ -78,20 +78,22 @@ int main(void)
             camera.offset = SCREEN_MIDDLE;
         }
 
-        float movement_speed = 10.0f * DT * 50;
-        if ((key_down(KC_UP) || key_down(KC_DOWN)) && (key_down(KC_LEFT) || key_down(KC_RIGHT)))
-            movement_speed = sqrtf(movement_speed) * 2;
-        if (key_down(KC_CROUCH))
-            movement_speed /= 2.0f;
+        if (ninja_dash_time() <= EPSILON) {
+            float movement_speed = 10.0f * DT * 50;
+            if ((key_down(KC_UP) || key_down(KC_DOWN)) && (key_down(KC_LEFT) || key_down(KC_RIGHT)))
+                movement_speed = sqrtf(movement_speed) * 2;
+            if (key_down(KC_CROUCH))
+                movement_speed /= 2.0f;
 
-        if (key_down(KC_LEFT))
-            camera.target.x -= movement_speed ;
-        if (key_down(KC_RIGHT))
-            camera.target.x += movement_speed ;
-        if (key_down(KC_DOWN))
-            camera.target.y -= movement_speed ;
-        if (key_down(KC_UP))
-            camera.target.y += movement_speed ;
+            if (key_down(KC_LEFT))
+                camera.target.x -= movement_speed ;
+            if (key_down(KC_RIGHT))
+                camera.target.x += movement_speed ;
+            if (key_down(KC_DOWN))
+                camera.target.y -= movement_speed ;
+            if (key_down(KC_UP))
+                camera.target.y += movement_speed ;
+        }
 
         camera_bound(&camera, map.box, ninja_radius());
 
diff --git a/ninja.c b/ninja.c
index b560bf5..ab0a776 100644
--- a/ninja.c
+++ b/ninja.c
@@ -6,6 +6,8 @@
 
 Texture ninja_texture;
 
+float dash_time = 0;
+
 void load_ninja()
 {
     ninja_texture = LoadTexture("data/ninja.png");
@@ -16,21 +18,39 @@ float ninja_radius()
     return fmax(ninja_texture.width, ninja_texture.height)/2;
 }
 
-Vector2 ninja_dash(Vector2 pos)
+Vector2 ninja_dash(Vector2 pos, Vector2 to, float sec)
 {
+    static Vector2 target = {0};
     Vector2 dash = {0};
-    Vector2 mouse = GetMousePosition();
-    Vector2 diff = Vector2Subtract(mouse, pos);
-    dash = Vector2Normalize(diff);
-    dash.x *= 100;
-    dash.y *= 100;
+    if (sec <= EPSILON)
+        return dash;
+    if (key_pressed(KC_SHOOT)) {
+        dash_time = sec;
+        Vector2 diff = Vector2Subtract(to, pos);
+        Vector2 scale = Vector2Normalize(diff);
+        int dist = 200;
+        scale.x *= dist;
+        scale.y *= dist;
+        target = Vector2Add(pos, scale);
+    }
+    if (dash_time > 0) {
+        float dt = GetFrameTime();
+        dash_time -= dt;
+        dash.x = Lerp(pos.x, target.x, dt/sec) - pos.x;
+        dash.y = Lerp(pos.y, target.y, dt/sec) - pos.y;
+    }
     return dash;
 }
 
+float ninja_dash_time()
+{
+    return dash_time;
+}
+
 void draw_ninja(Vector2 pos, Camera2D *cam)
 {
-    if (key_pressed(KC_SHOOT))
-        cam->target = Vector2Add(cam->target, ninja_dash(pos));
+    Vector2 dash = ninja_dash(GetScreenToWorld2D(pos, *cam), GetScreenToWorld2D(GetMousePosition(), *cam), 0.12);
+    cam->target = Vector2Add(cam->target, dash);
     Texture n = ninja_texture;
 
     Rectangle source = {0, 0, n.width, n.height};
diff --git a/ninja.h b/ninja.h
index 6ac390e..3fcd23a 100644
--- a/ninja.h
+++ b/ninja.h
@@ -7,4 +7,6 @@ float ninja_radius();
 
 void draw_ninja(Vector2 pos, Camera2D *cam);
 
+float ninja_dash_time();
+
 #endif // NINJA_H