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) に設定するため、このソリューションは問題になります。

4

1 に答える 1

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;

}
于 2015-12-29T14:17:48.553 に答える