Gerakan mouse relatif dan CoreWindow

Dalam permainan, mouse adalah opsi kontrol umum yang akrab bagi banyak pemain, dan juga penting untuk banyak genre game, termasuk penembak orang pertama dan ketiga, dan game strategi real-time. Di sini kita membahas implementasi kontrol mouse relatif, yang tidak menggunakan kursor sistem dan tidak mengembalikan koordinat layar absolut; sebagai gantinya, mereka melacak delta piksel di antara gerakan mouse.

Beberapa aplikasi, seperti game, menggunakan mouse sebagai perangkat input yang lebih umum. Misalnya, modeler 3-D mungkin menggunakan input mouse untuk mengorientasikan objek 3-D dengan mensimulasikan trackball virtual; atau permainan mungkin menggunakan mouse untuk mengubah arah kamera melihat melalui kontrol tampilan mouse.

Dalam skenario ini, aplikasi memerlukan data mouse relatif. Nilai mouse relatif mewakili seberapa jauh mouse bergerak sejak bingkai terakhir, bukan nilai koordinat x-y absolut dalam jendela atau layar. Selain itu, aplikasi sering menyembunyikan kursor mouse karena posisi kursor sehubungan dengan koordinat layar tidak relevan saat memanipulasi objek atau adegan 3-D.

Saat pengguna mengambil tindakan yang memindahkan aplikasi ke mode manipulasi objek/adegan 3-D relatif, aplikasi harus:

  • Abaikan penanganan mouse default.
  • Aktifkan penanganan mouse relatif.
  • Sembunyikan kursor mouse dengan mengaturnya penunjuk null (nullptr).

Saat pengguna mengambil tindakan yang memindahkan aplikasi dari mode manipulasi objek/adegan 3-D relatif, aplikasi harus:

  • Aktifkan penanganan mouse default/absolut.
  • Matikan penanganan mouse relatif.
  • Atur kursor mouse ke nilai non-null (yang membuatnya terlihat).

Catatan
Dengan pola ini, lokasi kursor mouse absolut dipertahankan saat memasuki mode relatif tanpa kursor. Kursor muncul kembali di lokasi koordinat layar yang sama seperti sebelumnya untuk mengaktifkan mode pergerakan mouse relatif.

Menangani gerakan mouse relatif

Untuk mengakses nilai delta mouse relatif, daftar untuk peristiwa MouseDevice::MouseMoved seperti yang ditunjukkan di sini.



// 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;
}

Penanganan aktivitas dalam contoh kode ini, OnMouseMoved, merender tampilan berdasarkan gerakan mouse. Posisi penunjuk mouse diteruskan ke handler sebagai objek MouseEventArgs .

Lewati pemrosesan data mouse absolut dari peristiwa CoreWindow::P ointerMoved saat aplikasi Anda berubah untuk menangani nilai pergerakan mouse relatif. Namun, hanya lewati input ini jika peristiwa CoreWindow::P ointerMoved terjadi sebagai hasil input mouse (dibandingkan dengan input sentuhan). Kursor disembunyikan dengan mengatur CoreWindow::P ointerCursor ke nullptr.

Kembali ke gerakan mouse absolut

Ketika aplikasi keluar dari objek 3-D atau mode manipulasi adegan dan tidak lagi menggunakan gerakan mouse relatif (seperti ketika kembali ke layar menu), kembali ke pemrosesan normal gerakan mouse absolut. Saat ini, berhenti membaca data mouse relatif, mulai ulang pemrosesan peristiwa mouse standar (dan penunjuk), dan atur CoreWindow::P ointerCursor ke nilai non-null.

Catatan
Saat aplikasi Anda berada dalam mode manipulasi objek/adegan 3-D (memproses gerakan mouse relatif dengan kursor mati), mouse tidak dapat memanggil antarmuka pengguna tepi seperti tombol, tumpukan belakang, atau bilah aplikasi. Oleh karena itu, penting untuk menyediakan mekanisme untuk keluar dari mode khusus ini, seperti kunci Esc yang umum digunakan.