相對滑鼠移動和 CoreWindow
在遊戲中,滑鼠是許多玩家熟悉的常用控制選項,對很多遊戲類型也是必要裝置,包括第一和第三人稱角度射擊,以及即時策略遊戲。 在本文中,我們將討論相對滑鼠控制項的實作,這不會使用系統游標,也不會傳回絕對螢幕座標;而是追蹤滑鼠移動之間的像素差異。
有些應用程式 (例如遊戲) 更常以滑鼠作為輸入裝置。 例如,3D 模組工具使用滑鼠時,可能會模擬虛擬軌跡球來定位 3D 物件;或者遊戲使用滑鼠時,會透過滑鼠的視角控制項,變更檢視相機的方向。
在這些案例中,應用程式需要相對滑鼠資料。 相對滑鼠值代表滑鼠自最後一格畫面以來移動的距離,而非視窗或畫面內的絕對 x-y 座標值。 此外,應用程式通常會隱藏滑鼠游標,因為對於操作 3D 物件或場景來說,游標相對於螢幕座標的位置並不相關。
當使用者採取動作,將應用程式移至相對 3D 物件/場景的操作模式,應用程式必須:
- 忽略預設的滑鼠處理。
- 啟用相對滑鼠處理。
- 將滑鼠游標設為 null 指標 (nullptr),即可隱藏滑鼠游標。
當使用者採取動作,將應用程式移出相對 3D 物件/場景的操作模式,應用程式必須:
- 啟用預設/絕對滑鼠處理。
- 關閉相對滑鼠處理。
- 將滑鼠游標設為非 null 值 (使游標可見)。
注意
如果使用此模式,絕對滑鼠游標位置會保留在進入無游標相對模式時。 游標會重新出現在先前啟用相對滑鼠移動模式時,所在的同一個螢幕座標位置。
處理相對滑鼠移動
若要存取相對滑鼠差異值,請註冊 MouseDevice::MouseMoved 事件 (如這裡所示)。
// register handler for relative mouse movement events
Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved +=
ref new TypedEventHandler<MouseDevice^, MouseEventArgs^>(this, &MoveLookController::OnMouseMoved);
void MoveLookController::OnMouseMoved(
_In_ Windows::Devices::Input::MouseDevice^ mouseDevice,
_In_ Windows::Devices::Input::MouseEventArgs^ args
)
{
float2 pointerDelta;
pointerDelta.x = static_cast<float>(args->MouseDelta.X);
pointerDelta.y = static_cast<float>(args->MouseDelta.Y);
float2 rotationDelta;
rotationDelta = pointerDelta * ROTATION_GAIN; // scale for control sensitivity
// update our orientation based on the command
m_pitch -= rotationDelta.y; // mouse y increases down, but pitch increases up
m_yaw -= rotationDelta.x; // yaw defined as CCW around y-axis
// limit pitch to straight up or straight down
float limit = (float)(M_PI/2) - 0.01f;
m_pitch = (float) __max( -limit, m_pitch );
m_pitch = (float) __min( +limit, m_pitch );
// keep longitude in useful range by wrapping
if ( m_yaw > M_PI )
m_yaw -= (float)M_PI*2;
else if ( m_yaw < -M_PI )
m_yaw += (float)M_PI*2;
}
此程式碼範例中的事件處理常式 OnMouseMoved 會根據滑鼠移動轉譯檢視。 滑鼠指標的位置會以 MouseEventArgs 物件形式傳遞至處理常式。
當應用程式變更為處理相對滑鼠移動值時,請略過處理來自 CoreWindow::PointerMoved 事件的絕對滑鼠資料。 不過,只有當 CoreWindow::PointerMoved 事件是產生自滑鼠輸入 (而非觸控輸入),才能略過此輸入。 將 CoreWindow::PointerCursor 設為 nullptr 即可隱藏游標。
回到絕對滑鼠移動
一旦應用程式結束 3D 物件或場景操作模式,且不再使用相對滑鼠移動 (例如返回功能表畫面時),則回到正常的絕對滑鼠移動處理方式。 此時請停止讀取相對滑鼠資料、重新開始處理標準滑鼠 (和指標) 事件,並將 CoreWindow::PointerCursor 設為非 null 值。
注意
當應用程式處於 3D 物件/場景操作模式 (處理相對滑鼠移動且滑鼠為關閉狀態),滑鼠將無法叫用 Edge UI,例如:快速鍵、上一頁堆疊或應用程式列。 因此,請務必提供一個能結束此特定模式的機制,例如常用的 Esc 鍵。