Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
DirectX ile Evrensel Windows Platformu (UWP) C++ oyununuza temel dokunma denetimleri eklemeyi öğrenin. Direct3D ortamında sabit düzlemli kamerayı hareket ettirmek için dokunmatik tabanlı denetimlerin nasıl ekleneceğini gösteriyoruz. Burada parmakla veya ekran kalemiyle sürüklemek kamera perspektifini değiştirir.
Bu denetimleri, oyuncunun harita veya oyun alanı gibi bir 3B ortamda kaydırmak veya gezmek için sürüklemesini istediğiniz oyunlara ekleyebilirsiniz. Örneğin, bir strateji veya bulmaca oyununda, oyuncunun sola veya sağa doğru kaydırma yaparak ekrandan daha büyük bir oyun ortamını görüntülemesine izin vermek için bu denetimleri kullanabilirsiniz.
Not Kodumuz fare tabanlı kaydırma denetimleriyle de çalışır. İşaretçiyle ilgili olaylar Windows Çalışma Zamanı API'leri tarafından soyutlanır, böylece dokunma veya fare tabanlı işaretçi olaylarını işleyebilir.
Hedef
- DirectX oyununda sabit düzlemli bir kamerayı kaydırmak için basit bir dokunmatik sürükleme denetimi oluşturun.
Temel dokunmatik olay altyapısını ayarlama
İlk olarak, bu örnekte temel denetleyici türü olan CameraPanControllertanımlayacağız. Burada, kullanıcının gerçekleştirebileceği davranış kümesi olan bir denetleyiciyi soyut bir fikir olarak tanımlayacağız.
CameraPanController sınıfı, kamera denetleyicisi durumu hakkında düzenli olarak yenilenen bir bilgi koleksiyonudur ve uygulamamızın bu bilgileri güncelleştirme döngüsünden alması için bir yol sağlar.
using namespace Windows::UI::Core;
using namespace Windows::System;
using namespace Windows::Foundation;
using namespace Windows::Devices::Input;
#include <directxmath.h>
// Methods to get input from the UI pointers
ref class CameraPanController
{
}
Şimdi, kamera denetleyicisinin durumunu tanımlayan ve kamera denetleyici etkileşimlerini uygulayan temel yöntemler ile olay işleyicilerini içeren bir başlık oluşturalım.
ref class CameraPanController
{
private:
// Properties of the controller object
DirectX::XMFLOAT3 m_position; // the position of the camera
// Properties of the camera pan control
bool m_panInUse;
uint32 m_panPointerID;
DirectX::XMFLOAT2 m_panFirstDown;
DirectX::XMFLOAT2 m_panPointerPosition;
DirectX::XMFLOAT3 m_panCommand;
internal:
// Accessor to set the position of the controller
void SetPosition( _In_ DirectX::XMFLOAT3 pos );
// Accessor to set the fixed "look point" of the controller
DirectX::XMFLOAT3 get_FixedLookPoint();
// Returns the position of the controller object
DirectX::XMFLOAT3 get_Position();
public:
// Methods to get input from the UI pointers
void OnPointerPressed(
_In_ Windows::UI::Core::CoreWindow^ sender,
_In_ Windows::UI::Core::PointerEventArgs^ args
);
void OnPointerMoved(
_In_ Windows::UI::Core::CoreWindow^ sender,
_In_ Windows::UI::Core::PointerEventArgs^ args
);
void OnPointerReleased(
_In_ Windows::UI::Core::CoreWindow^ sender,
_In_ Windows::UI::Core::PointerEventArgs^ args
);
// Set up the Controls supported by this controller
void Initialize( _In_ Windows::UI::Core::CoreWindow^ window );
void Update( Windows::UI::Core::CoreWindow ^window );
}; // Class CameraPanController
Özel alanlar, kamera denetleyicisinin geçerli durumunu içerir. Şimdi bunları gözden geçirelim.
- m_position, kameranın sahne alanında konumudur. Bu örnekte z koordinat değeri 0 olarak sabittir. Bu değeri temsil etmek için bir DirectX::XMFLOAT2 kullanabiliriz, ancak bu örnek ve gelecekteki genişletilebilirlik amacıyla DirectX::XMFLOAT3 kullanırız. Görünüm penceresini uygun şekilde güncelleştirebilmesi için bu değeri get_Position özelliğinden uygulamanın kendisine geçiririz.
- m_panInUse, kaydırma işleminin etkin olup olmadığını gösteren bir Boole değeridir; veya daha belirgin olarak, oyuncunun ekrana dokunup dokunmadığı ve kamerayı hareket ettirip taşımadığı.
- m_panPointerID, işaretçi için benzersiz bir kimliktir. Bunu örnekte kullanmayacağız, ancak denetleyici durum sınıfınızı belirli bir işaretçiyle ilişkilendirmek iyi bir uygulamadır.
- m_panFirstDown, ekranda oyuncunun ekrana ilk dokunduğu veya kamera kaydırma eylemi sırasında fareye tıkladığı noktadır. Bu değeri daha sonra ekrana dokunulduğunda veya fare biraz sallandığında titreşimi önlemek için bir ölü bölge ayarlamak amacıyla kullanırız.
- m_panPointerPosition, ekranda oyuncunun şu anda işaretçiyi hareket ettirdiği noktadır. Oyuncunun hangi yöne hareket etmek istediğini, m_panFirstDown'e göre inceleyerek belirlemek için bunu kullanırız.
- m_panCommand, kamera denetleyicisinin son hesaplanan komutudur: yukarı, aşağı, sol veya sağ. x-y düzlemine sabitlenmiş bir kamera ile çalıştığımız için bu bir DirectX::XMFLOAT2 değeri olabilir.
Kamera denetleyicisi durum bilgilerini güncelleştirmek için bu 3 olay işleyicisini kullanırız.
- OnPointerPressed, oyuncuların dokunma yüzeyine bir parmak bastığı ve işaretçinin basma noktasının koordinatlarına taşındığı zaman uygulamamızın çağırdığı bir olay işleyicisidir.
- OnPointerMoved, oynatıcı dokunmatik yüzey üzerinde bir parmağı kaydırdığında uygulamamızın çağırmış olduğu bir olay işleyicidir. Sürükleme yolunun yeni koordinatlarıyla güncellenir.
- OnPointerReleased, oyuncu dokunmatik yüzeyden basma parmağını kaldırdığında uygulamamızın çağırdığı bir olay işleyicidir.
Son olarak, kamera denetleyicisi durum bilgilerini başlatmak, erişmek ve güncelleştirmek için bu yöntemleri ve özellikleri kullanırız.
- Initialize, uygulamamızın denetimleri başlatmak ve bunları görüntüleme pencerenizi açıklayan CoreWindow nesnesine eklemek için çağırdığı bir olay işleyicidir.
- SetPosition, uygulamamızın sahne alanında denetimlerinizin (x, y ve z) koordinatlarını ayarlamak için çağıran bir yöntemdir. Bu öğretici boyunca z koordinatımızın 0 olduğunu unutmayın.
- get_Position, sahne alanında kameranın geçerli konumunu almak için uygulamamızın eriştiği bir özelliktir. Geçerli kamera konumunu uygulamaya iletmenin yolu olarak bu özelliği kullanırsınız.
- get_FixedLookPoint, uygulamamızın denetleyici kameranın karşı karşıya olduğu geçerli noktaya erişmek için kullandığı bir özelliktir. Bu örnekte, x-y düzlemine normal şekilde kilitlenir.
- Update, denetleyici durumunu okuyan ve kamera konumunu güncelleştiren bir yöntemdir. Bu <, kamera denetleyicisi verilerini ve sahne alanındaki kamera konumunu yenilemek için uygulamanın ana döngüsünden> bir şeyi sürekli çağırırsınız.
Şimdi, dokunmatik denetimleri uygulamak için ihtiyacınız olan tüm bileşenler buradadır. Dokunma veya fare işaretçisi olaylarının ne zaman ve nerede gerçekleştiğini ve eylemin ne olduğunu algılayabilirsiniz. Kameranın sahne alanına göre konumunu ve yönünü ayarlayabilir ve değişiklikleri izleyebilirsiniz. Son olarak, yeni kamera konumunu arama uygulamasına iletebilirsiniz.
Şimdi bu parçaları birbirine bağlayalım.
Temel dokunma olaylarını oluşturma
Windows Çalışma Zamanı olay dağıtıcısı, uygulamamızın işlemesini istediğimiz 3 olay sağlar:
- İşaretçiBasılı
- İşaretçi Taşındı
- İşaretçiSerbestBırakıldı
Bu olaylar CoreWindow türünde uygulanır. Çalışabileceğiniz bir CoreWindow nesneniz olduğunu varsayıyoruz. Daha fazla bilgi için bkz. UWP C++ uygulamanızı DirectX görünümünügörüntüleyecek şekilde ayarlama.
Bu olaylar uygulamamız çalışırken tetiklendiğinden, işleyiciler özel alanlarımızda tanımlanan kamera denetleyicisi durum bilgilerini güncelleştirir.
İlk olarak, dokunma işaretçisi olay işleyicilerini dolduralım. onPointerPressed
OnPointerPressed
void CameraPanController::OnPointerPressed(
_In_ CoreWindow^ sender,
_In_ PointerEventArgs^ args)
{
// Get the current pointer position.
uint32 pointerID = args->CurrentPoint->PointerId;
DirectX::XMFLOAT2 position = DirectX::XMFLOAT2( args->CurrentPoint->Position.X, args->CurrentPoint->Position.Y );
auto device = args->CurrentPoint->PointerDevice;
auto deviceType = device->PointerDeviceType;
if ( !m_panInUse ) // If no pointer is in this control yet.
{
m_panFirstDown = position; // Save the location of the initial contact.
m_panPointerPosition = position;
m_panPointerID = pointerID; // Store the id of the pointer using this control.
m_panInUse = TRUE;
}
}
Geçerli CameraPanController örneğine, m_panInUse TRUE olarak ayarlayarak kamera denetleyicisinin etkin olarak ele alınması gerektiğini bildirmek için bu işleyiciyi kullanırız. Bu şekilde, uygulama Update çağırdığında, görünüm penceresi güncelleştirmek için geçerli konum verilerini kullanır.
Kullanıcı ekrana dokunduğunda veya görüntüleme penceresinde tıklayarak bastığında kamera hareketinin temel değerlerini belirlediğimize göre, kullanıcı ekrana sürükleme yaptığında veya fareyi düğmeye basılı tutarak hareket ettirdiğinde ne yapacağımızı belirlememiz gerekir.
OnPointerMoved olay işleyicisi, kullanıcı işaretçiyi ekranda sürüklerken her adımda işaretçi hareket ettiğinde tetiklenir. Uygulamayı işaretçinin geçerli konumunun farkında tutmamız gerekir ve bunu bu şekilde yaparız.
İşaretçi Taşındı
void CameraPanController::OnPointerMoved(
_In_ CoreWindow ^sender,
_In_ PointerEventArgs ^args)
{
uint32 pointerID = args->CurrentPoint->PointerId;
DirectX::XMFLOAT2 position = DirectX::XMFLOAT2( args->CurrentPoint->Position.X, args->CurrentPoint->Position.Y );
m_panPointerPosition = position;
}
Son olarak, oynatıcı ekrana dokunmayı durdurduğunda kamera kaydırma davranışını devre dışı bırakmamız gerekir. OnPointerReleased, PointerReleased tetiklendiğinde çağrılır, bu da m_panInUse'i FALSE olarak ayarlamak, kamera kaydırma hareketini kapatmak ve işaretçi kimliğini 0 olarak ayarlamak için kullanılır.
PointerSerbestBırakıldı
void CameraPanController::OnPointerReleased(
_In_ CoreWindow ^sender,
_In_ PointerEventArgs ^args)
{
uint32 pointerID = args->CurrentPoint->PointerId;
DirectX::XMFLOAT2 position = DirectX::XMFLOAT2( args->CurrentPoint->Position.X, args->CurrentPoint->Position.Y );
m_panInUse = FALSE;
m_panPointerID = 0;
}
Dokunma denetimlerini ve denetleyici durumunu başlatma
Olayları bağlayalım ve kamera denetleyicisinin tüm temel durum alanlarını başlatalım.
Başlat
void CameraPanController::Initialize( _In_ CoreWindow^ window )
{
// Start receiving touch/mouse events.
window->PointerPressed +=
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &CameraPanController::OnPointerPressed);
window->PointerMoved +=
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &CameraPanController::OnPointerMoved);
window->PointerReleased +=
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &CameraPanController::OnPointerReleased);
// Initialize the state of the controller.
m_panInUse = FALSE;
m_panPointerID = 0;
// Initialize this as it is reset on every frame.
m_panCommand = DirectX::XMFLOAT3( 0.0f, 0.0f, 0.0f );
}
Initialize, uygulamanın CoreWindow örneğine bir parametre olarak başvuru alır ve geliştirdiğimiz olay işleyicilerini ilgili CoreWindowüzerinde uygun olaylara kaydeder.
Kamera denetleyicisinin konumunu alma ve ayarlama
Kamera denetleyicisinin sahne alanında konumunu almak ve ayarlamak için bazı yöntemler tanımlayalım.
void CameraPanController::SetPosition( _In_ DirectX::XMFLOAT3 pos )
{
m_position = pos;
}
// Returns the position of the controller object
DirectX::XMFLOAT3 CameraPanController::get_Position()
{
return m_position;
}
DirectX::XMFLOAT3 CameraPanController::get_FixedLookPoint()
{
// For this sample, we don't need to use the trig functions because our
// look point is fixed.
DirectX::XMFLOAT3 result= m_position;
result.z += 1.0f;
return result;
}
SetPosition, kamera denetleyicisi konumunu belirli bir noktaya ayarlamamız gerekirse uygulamamızdan çağırabileceğiniz genel bir yöntemdir.
get_Position en önemli ortak özelliğimizdir: uygulamamız kamera denetleyicisinin sahne alanında geçerli konumunu alır ve böylece görünüm penceresini uygun şekilde güncelleştirebilir.
get_FixedLookPoint, bu örnekte x-y düzlemine dik bir bakış noktasını edinen genel bir özelliktir. Sabit kamera için daha eğik açılar oluşturmak istiyorsanız bu yöntemi x, y ve z koordinat değerlerini hesaplarken sin ve cos trigonometrik işlevlerini kullanacak şekilde değiştirebilirsiniz.
Kamera denetleyicisi durum bilgilerini güncelleştirme
Şimdi, m_panPointerPosition izlenen işaretçi koordinat bilgilerini 3B sahne alanımızla ilgili yeni koordinat bilgilerine dönüştüren hesaplamalarımızı yapıyoruz. Ana uygulama döngüsünü her yenilediğimizde uygulamamız bu yöntemi çağırır. Burada, görünüm penceresine yansıtmadan önce görünüm matrisini güncelleştirmek için kullanılan uygulamaya geçirmek istediğimiz yeni konum bilgilerini hesaplıyoruz.
void CameraPanController::Update( CoreWindow ^window )
{
if ( m_panInUse )
{
pointerDelta.x = m_panPointerPosition.x - m_panFirstDown.x;
pointerDelta.y = m_panPointerPosition.y - m_panFirstDown.y;
if ( pointerDelta.x > 16.0f ) // Leave 32 pixel-wide dead spot for being still.
m_panCommand.x += 1.0f;
else
if ( pointerDelta.x < -16.0f )
m_panCommand.x += -1.0f;
if ( pointerDelta.y > 16.0f )
m_panCommand.y += 1.0f;
else
if (pointerDelta.y < -16.0f )
m_panCommand.y += -1.0f;
}
DirectX::XMFLOAT3 command = m_panCommand;
// Our velocity is based on the command.
DirectX::XMFLOAT3 Velocity;
Velocity.x = command.x;
Velocity.y = command.y;
Velocity.z = 0.0f;
// Integrate
m_position.x = m_position.x + Velocity.x;
m_position.y = m_position.y + Velocity.y;
m_position.z = m_position.z + Velocity.z;
// Clear the movement input accumulator for use during the next frame.
m_panCommand = DirectX::XMFLOAT3( 0.0f, 0.0f, 0.0f );
}
Dokunma veya fare titremesinin kameramızı sarsıntılı hale getirmesini istemediğimiz için işaretçinin etrafında 32 piksel çapında bir ölü bölge ayarladık. Ayrıca bir hız değerimiz de vardır. Bu örnekte, işaretçinin ölü bölgeden piksel geçişiyle 1:1'dir. Hareket hızını yavaşlatmak veya hızlandırmak için bu davranışı ayarlayabilirsiniz.
Görünüm matrisini yeni kamera konumuyla güncelleştirme
Artık kameramızın odaklandığı ve uygulamanıza bunu her istediğinizde güncelleştirilen bir sahne alanı koordinatı elde edebiliriz (örneğin, ana uygulama döngüsünde her 60 saniyede bir). Bu sahte kod, uygulayabileceğiniz çağırma davranışını önerir:
myCameraPanController->Update( m_window );
// Update the view matrix based on the camera position.
myCamera->MyMethodToComputeViewMatrix(
myController->get_Position(), // The position in the 3D scene space.
myController->get_FixedLookPoint(), // The point in the space we are looking at.
DirectX::XMFLOAT3( 0, 1, 0 ) // The axis that is "up" in our space.
);
Tebrikler! Oyununuzda basit bir kamera kaydırmalı dokunmatik denetim kümesi uyguladınız.