2015-12-21 22 views
0

好的,所以我嘗試使用遊戲板上的模擬杆來移動桌面鼠標光標。問題是我需要能夠獲得與嘗試2相同的平滑度,但不使用絕對的鼠標位置。光標需要相對於其當前位置移動。原因是許多應用程序(主要是視頻遊戲)也將鼠標設置爲絕對位置。這會導致應用程序和嘗試2相互爭奪鼠標的控制權。如何將控制器模擬杆映射到鼠標

嘗試1(相對)

// keep updating the controller state and mouse position 
while (true) 
{ 
    // getState returns a 2d float vector with normalized values from [-1, 1] 
    // The cursor is being set relative to its current position here. 
    SetCursorPosition(GetCursorPosition() + analogStick->getState()); 
} 

此解決方案,但由於GetCursorPosition和SetCursorPosition基於整數從一個四捨五入的問題困擾。因此,小的移動不會被註冊,因爲較小的模擬移動總會被截斷。從視覺上講,即使您嘗試進行對角線移動,模擬杆上的小動作也只會沿着X或Y軸移動鼠標。

嘗試2(絕對)

vec2 mouseTargetPosition = GetCursorPosition(); // global cursor position 
while (true) 
{ 
    mouseTargetPosition += leftStick->getState(); 
    vec2 newPosition = lerp(GetCursorPos(), mouseTargetPosition, 0.8f); 
    SetCursorPos(round(newPosition.x), round(newPosition.y)); 
} 

此解決方案大,鼠標響應最小的運動的和非常自然地內插的累積模擬移動的結果移動。但是,它將鼠標設置爲絕對位置(mouseTargetPosition),從而使該解決方案成爲交易斷路器。

回答

0

這是一個非常具體的問題,我首先想到的。經過幾種配置後,這是一個感覺最流暢,效果很好的產品。這基本上是魔術考慮因爲它可以添加本機感覺模擬支持遊戲和模型觀衆沒有它:)

vec2 mouseTargetPos, mouseCurrentPos, change; 
while (true) 
{ 
    // Their actual position doesn't matter so much as how the 'current' vector approaches 
    // the 'target vector' 
    mouseTargetPos += primary->state; 
    mouseCurrentPos = util::lerp(mouseCurrentPos, mouseTargetPos, 0.75f); 
    change = mouseTargetPos - mouseCurrentPos; 

    // movement was too small to be recognized, so we accumulate it 
    if (fabs(change.x) < 0.5f) accumulator.x += change.x; 
    if (fabs(change.y) < 0.5f) accumulator.y += change.y; 

    // If the value is too small to be recognized (< 0.5) then the position will remain the same 
    SetCursorPos(GetCursorPos() + change); 
    SetCursorPos(GetCursorPos() + accumulator); 

    // once the accumulator has been used, reset it for the next accumulation. 
    if (fabs(accumulator.x) >= 0.5f) accumulator.x = 0; 
    if (fabs(accumulator.y) >= 0.5f) accumulator.y = 0; 

}