diff --git a/gdrust/src/lib.rs b/gdrust/src/lib.rs
index 97c8108..8f75de0 100644
--- a/gdrust/src/lib.rs
+++ b/gdrust/src/lib.rs
@@ -7,8 +7,27 @@ mod weapons;
 mod zenith;
 
 use godot::prelude::*;
+use std::panic::{set_hook, PanicInfo};
 
 struct GdExtension;
 
+fn panic_handler(info: &PanicInfo) {
+    if let Some(p) = info.location() {
+        godot_error!(
+            "Panic occurred in file '{}' at line {}\n",
+            p.file(),
+            p.line()
+        );
+    } else {
+        godot_error!("Panic occurred but can't get location information.");
+    }
+}
+
 #[gdextension()]
-unsafe impl ExtensionLibrary for GdExtension {}
+unsafe impl ExtensionLibrary for GdExtension {
+    fn on_level_init(level: InitLevel) {
+        if level == InitLevel::Scene {
+            set_hook(Box::new(panic_handler))
+        }
+    }
+}
diff --git a/gdrust/src/player.rs b/gdrust/src/player.rs
index 0e1ab12..cb51553 100644
--- a/gdrust/src/player.rs
+++ b/gdrust/src/player.rs
@@ -12,7 +12,7 @@ pub struct Player {
     base: Base<CharacterBody2D>,
     status: Movement,
     /// 上一次点击克盾冲刺键的时间,记录来判断双击
-    click_time: Instant,
+    click_time: Option<Instant>,
     /// 上一次的类型
     click_type: Click,
 }
@@ -41,6 +41,7 @@ const MOVE_LEFT: &str = "move_left";
 const MOVE_UP: &str = "move_up";
 const MOVE_DOWN: &str = "move_down";
 const SLOW_DOWN: &str = "slow_down";
+const DOUBLE_CLICK_DURATION: Duration = Duration::from_millis(500);
 
 #[godot_api()]
 impl ICharacterBody2D for Player {
@@ -50,7 +51,7 @@ impl ICharacterBody2D for Player {
             base,
             health: Self::MAX_HEALTH,
             status: Movement::Move,
-            click_time: Instant::now(),
+            click_time: None,
             click_type: Click::None,
         }
     }
@@ -59,16 +60,16 @@ impl ICharacterBody2D for Player {
 
     fn physics_process(&mut self, delta: f64) {
         let input_obj = Input::singleton();
-        let mut speed = Self::SPEED;
+        let mut down_rate = 1.0;
         if input_obj.is_action_pressed(SLOW_DOWN.into()) {
-            speed /= 2;
+            down_rate = 0.5;
         }
         if self.status == Movement::Rush {
             godot_print!("rush inside!");
             let vel = Vector2::new(
                 match self.click_type {
-                    Click::Left => -Self::RUSH_SPEED as f32,
-                    Click::Right => Self::RUSH_SPEED as f32,
+                    Click::Left => -1.0,
+                    Click::Right => 1.0,
                     _ => {
                         let msg = format!("wrong movement {:?} when rush", self.click_type);
                         godot_error!("{}", &msg);
@@ -77,8 +78,9 @@ impl ICharacterBody2D for Player {
                 },
                 0.0,
             );
-            self.base_mut()
-                .move_and_collide(vel * delta as f32 * speed as f32);
+            self.base_mut().move_and_collide(
+                vel.normalized() * Self::RUSH_SPEED as f32 * delta as f32 * down_rate as f32,
+            );
             return;
         }
         let mut vel = Vector2::ZERO;
@@ -89,32 +91,15 @@ impl ICharacterBody2D for Player {
             vel.x += 1.0;
         }
         // 触发克盾
-        if input_obj.is_action_just_pressed(MOVE_LEFT.into())
-            && self.click_type == Click::Left
-            && self.click_time.elapsed() < Duration::new(0, 100 * 1000)
-        {
-            self.start_rush();
-        }
-        if input_obj.is_action_just_pressed(MOVE_LEFT.into())
-            && self.click_type == Click::Left
-            && self.click_time.elapsed() < Duration::new(0, 100 * 1000)
-        {
-            self.start_rush();
-        }
-        // 记录克盾第一次按按钮
-        if input_obj.is_action_just_released(MOVE_RIGHT.into()) {
-            self.click_time = Instant::now();
-            self.click_type = Click::Right;
-        }
-        if input_obj.is_action_just_released(MOVE_LEFT.into()) {
-            self.click_time = Instant::now();
-            self.click_type = Click::Left;
+        self.process_rush(MOVE_LEFT.into(), Click::Left);
+        self.process_rush(MOVE_RIGHT.into(), Click::Right);
+        if input_obj.is_action_just_pressed(MOVE_UP.into()) {
+            self.click_type = Click::Up;
+            self.click_time = None;
         }
-        if input_obj.is_action_just_released(MOVE_DOWN.into()) {
+        if input_obj.is_action_just_pressed(MOVE_DOWN.into()) {
             self.click_type = Click::Down;
-        }
-        if input_obj.is_action_just_released(MOVE_UP.into()) {
-            self.click_type = Click::Up;
+            self.click_time = None;
         }
         if input_obj.is_action_pressed(MOVE_UP.into()) {
             vel.y -= 1.0;
@@ -124,7 +109,7 @@ impl ICharacterBody2D for Player {
         }
         let res = self
             .base_mut()
-            .move_and_collide(vel.normalized() * speed as f32 * delta as f32);
+            .move_and_collide(vel.normalized() * Self::SPEED as f32 * down_rate * delta as f32);
     }
 }
 
@@ -147,7 +132,6 @@ impl Player {
     }
 
     fn start_rush(&mut self) {
-        godot_print!("rush inside!");
         self.status = Movement::Rush;
         // 冲刺结束计时器
         let mut timer = self.base().get_node_as::<Timer>("Cthulhu");
@@ -163,10 +147,41 @@ impl Player {
 
     #[func]
     fn stop_rush(&mut self) {
-        godot_print!("rush!");
         let mut particle = self.get_virtual_particle();
         particle.set_emitting(false);
         self.status = Movement::Move;
         self.click_type = Click::None;
     }
+
+    fn process_rush(&mut self, movement_name: StringName, click_type: Click) {
+        let input_obj = Input::singleton();
+        if input_obj.is_action_just_pressed(movement_name) {
+            godot_print!("enter rust process");
+            // 先检查上一次按下的键是不是双击键
+            if self.click_type != click_type {
+                self.click_type = click_type;
+                return;
+            } // 判断第一次还是第二次
+            match self.click_time {
+                None => {
+                    // 第一次按下按钮,记录时间
+                    self.click_time = Some(Instant::now())
+                }
+                Some(t) => {
+                    // 第二次按下,比较两次中间的间隔
+                    let dur = t.elapsed();
+                    if dur <= DOUBLE_CLICK_DURATION {
+                        // 达成双击条件
+                        // 清除双击时间
+                        self.click_time = None;
+                        self.click_type = Click::None;
+                        self.start_rush();
+                    } else {
+                        // 否则将当前时间设为双击开头
+                        self.click_time = Some(Instant::now());
+                    }
+                }
+            }
+        }
+    }
 }