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.
Uyarı
Bu konu, DirectX öğretici serisi ile basit bir Evrensel Windows Platformu (UWP) oluşturma
Artık oyunumuzun 3B görselleri olduğuna göre, oyunun oyuncuya oyun durumu hakkında geri bildirim sağlayabilmesi için bazı 2B öğeler eklemeye odaklanmanın zamanı geldi. Bu, 3B grafik işlem hattı çıkışının üzerine basit menü seçenekleri ve başlık görüntüleme bileşenleri eklenerek gerçekleştirilebilir.
Uyarı
Bu örnek için en son oyun kodunu indirmediyseniz Direct3D örnek oyunbölümüne gidin. Bu örnek, büyük bir UWP özellik örnekleri koleksiyonunun bir parçasıdır. Örneği indirme talimatları için, Windows geliştirme için örnek uygulamalar sayfasına bakın.
Amaç
Direct2D kullanarak UWP DirectX oyunumuza aşağıdakiler dahil olmak üzere bir dizi kullanıcı arabirimi grafiği ve davranışı ekleyin:
- Hareket-bakış denetleyicisi sınır dikdörtgenleri de dahil olmak üzere gösterge ekranı.
- Oyun durumu menüleri
Kullanıcı arabirimi katmanı
Bir DirectX oyununda metin ve kullanıcı arabirimi öğelerini görüntülemenin birçok yolu olsa da, Direct2Dkullanmaya odaklanacağız. Metin öğeleri için DirectWrite de kullanacağız.
Direct2D, piksel tabanlı temel öğeler ve efektler çizmek için kullanılan bir 2B çizim API'leri kümesidir. Direct2D ile çalışmaya başlarken, işleri basit tutmak en iyisidir. Karmaşık düzenlerin ve arabirim davranışlarının zamana ve planlamaya ihtiyacı vardır. Oyununuz simülasyon ve strateji oyunlarında bulunanlar gibi karmaşık bir kullanıcı arabirimi gerektiriyorsa bunun yerine XAML kullanmayı göz önünde bulundurun.
Uyarı
UWP DirectX oyununda XAML ile kullanıcı arabirimi geliştirme hakkında bilgi için bkz. Örnek oyunu genişletme.
Direct2D, html ve XAML gibi kullanıcı arabirimleri veya düzenler için özel olarak tasarlanmamıştır. Listeler, kutular veya düğmeler gibi kullanıcı arabirimi bileşenleri sağlamaz. Ayrıca divs, tablolar veya kılavuzlar gibi düzen bileşenleri sağlamaz.
Bu örnek oyun için iki ana kullanıcı arabirimi bileşenimiz var.
- Puan ve oyun içi kontroller için bir uyarı ekranı.
- Duraklatma bilgileri ve düzey başlangıç seçenekleri gibi oyun durumu metinlerini ve seçeneklerini görüntülemek için kullanılan katman.
Uyarı ekranı için Direct2D kullanma
Aşağıdaki görüntüde örnek için oyun içi uyarı ekranı gösterilmektedir. Bu, basit ve sade bir yapı sunarak oyuncunun 3B dünyada gezinmeye ve hedefleri vurmaya odaklanmasına olanak tanır. İyi bir arayüz veya uyarı ekranı, oyuncunun oyundaki olayları işleme ve tepki verme becerisini asla karmaşık hale getirmek zorunda değildir.
Katman, aşağıdaki temel ilkel nesnelerden oluşur.
-
Sağ üst köşede, oyuncuyu bilgilendiren DirectWrite metni
- Başarılı isabetler
- Oyuncunun yaptığı atış sayısı
- Düzeyde kalan süre
- Geçerli düzey numarası
- Çapraz saç oluşturmak için kullanılan iki kesişen çizgi segmenti
- Alt köşelerde, hareket-görünüm denetleyicisi sınırları için iki dikdörtgen.
Katmanın oyun içi uyarı görüntüleme durumu, GameHud sınıfının GameHud::Render yönteminde çizilir. Bu yöntemde, kullanıcı arabirimimizi temsil eden Direct2D katman, isabet sayısı, kalan süre ve düzey sayısındaki değişiklikleri yansıtacak şekilde güncelleştirilir.
Oyun başlatıldıysa, TotalHits()
arabelleğe TotalShots()
, TimeRemaining()
ve ekleyip yazdırma biçimini belirtiriz. Daha sonra DrawText yöntemini kullanarak çizebiliriz. Aynı işlemi geçerli düzey göstergesi için de yaparız, ➀ gibi tamamlanmamış düzeyleri ve belirli bir düzeyin tamamlandığını göstermek için ➊ gibi doldurulmuş sayıları göstermek için boş sayılar çizeriz.
Aşağıdaki kod parçacığı, GameHud::Render yönteminin işlemini göstermektedir
- **ID2D1RenderTarget::DrawBitmap** kullanarak Bitmap oluşturma **
- D2D1::RectF kullanarak kullanıcı arabirimi alanlarını dikdörtgenlere ayırma
- Metin öğeleri oluşturmak için DrawText kullanma
void GameHud::Render(_In_ std::shared_ptr<Simple3DGame> const& game)
{
auto d2dContext = m_deviceResources->GetD2DDeviceContext();
auto windowBounds = m_deviceResources->GetLogicalSize();
if (m_showTitle)
{
d2dContext->DrawBitmap(
m_logoBitmap.get(),
D2D1::RectF(
GameUIConstants::Margin,
GameUIConstants::Margin,
m_logoSize.width + GameUIConstants::Margin,
m_logoSize.height + GameUIConstants::Margin
)
);
d2dContext->DrawTextLayout(
Point2F(m_logoSize.width + 2.0f * GameUIConstants::Margin, GameUIConstants::Margin),
m_titleHeaderLayout.get(),
m_textBrush.get()
);
d2dContext->DrawTextLayout(
Point2F(GameUIConstants::Margin, m_titleBodyVerticalOffset),
m_titleBodyLayout.get(),
m_textBrush.get()
);
}
// Draw text for number of hits, total shots, and time remaining
if (game != nullptr)
{
// This section is only used after the game state has been initialized.
static const int bufferLength = 256;
static wchar_t wsbuffer[bufferLength];
int length = swprintf_s(
wsbuffer,
bufferLength,
L"Hits:\t%10d\nShots:\t%10d\nTime:\t%8.1f",
game->TotalHits(),
game->TotalShots(),
game->TimeRemaining()
);
// Draw the upper right portion of the HUD displaying total hits, shots, and time remaining
d2dContext->DrawText(
wsbuffer,
length,
m_textFormatBody.get(),
D2D1::RectF(
windowBounds.Width - GameUIConstants::HudRightOffset,
GameUIConstants::HudTopOffset,
windowBounds.Width,
GameUIConstants::HudTopOffset + (GameUIConstants::HudBodyPointSize + GameUIConstants::Margin) * 3
),
m_textBrush.get()
);
// Using the unicode characters starting at 0x2780 ( ➀ ) for the consecutive levels of the game.
// For completed levels start with 0x278A ( ➊ ) (This is 0x2780 + 10).
uint32_t levelCharacter[6];
for (uint32_t i = 0; i < 6; i++)
{
levelCharacter[i] = 0x2780 + i + ((static_cast<uint32_t>(game->LevelCompleted()) == i) ? 10 : 0);
}
length = swprintf_s(
wsbuffer,
bufferLength,
L"%lc %lc %lc %lc %lc %lc",
levelCharacter[0],
levelCharacter[1],
levelCharacter[2],
levelCharacter[3],
levelCharacter[4],
levelCharacter[5]
);
// Create a new rectangle and draw the current level info text inside
d2dContext->DrawText(
wsbuffer,
length,
m_textFormatBodySymbol.get(),
D2D1::RectF(
windowBounds.Width - GameUIConstants::HudRightOffset,
GameUIConstants::HudTopOffset + (GameUIConstants::HudBodyPointSize + GameUIConstants::Margin) * 3 + GameUIConstants::Margin,
windowBounds.Width,
GameUIConstants::HudTopOffset + (GameUIConstants::HudBodyPointSize + GameUIConstants::Margin) * 4
),
m_textBrush.get()
);
if (game->IsActivePlay())
{
// Draw the move and fire rectangles
...
// Draw the crosshairs
...
}
}
}
Yöntemi daha da açarak, GameHud::Render yönteminin bu parçası, ID2D1RenderTarget::DrawRectanglekullanarak hareket ve ateş dikdörtgenlerimizi ve iki çağrı ile ID2D1RenderTarget::DrawLinekullanarak nişangahları çizer.
// Check if game is playing
if (game->IsActivePlay())
{
// Draw a rectangle for the touch input for the move control.
d2dContext->DrawRectangle(
D2D1::RectF(
0.0f,
windowBounds.Height - GameUIConstants::TouchRectangleSize,
GameUIConstants::TouchRectangleSize,
windowBounds.Height
),
m_textBrush.get()
);
// Draw a rectangle for the touch input for the fire control.
d2dContext->DrawRectangle(
D2D1::RectF(
windowBounds.Width - GameUIConstants::TouchRectangleSize,
windowBounds.Height - GameUIConstants::TouchRectangleSize,
windowBounds.Width,
windowBounds.Height
),
m_textBrush.get()
);
// Draw the cross hairs
d2dContext->DrawLine(
D2D1::Point2F(windowBounds.Width / 2.0f - GameUIConstants::CrossHairHalfSize,
windowBounds.Height / 2.0f),
D2D1::Point2F(windowBounds.Width / 2.0f + GameUIConstants::CrossHairHalfSize,
windowBounds.Height / 2.0f),
m_textBrush.get(),
3.0f
);
d2dContext->DrawLine(
D2D1::Point2F(windowBounds.Width / 2.0f, windowBounds.Height / 2.0f -
GameUIConstants::CrossHairHalfSize),
D2D1::Point2F(windowBounds.Width / 2.0f, windowBounds.Height / 2.0f +
GameUIConstants::CrossHairHalfSize),
m_textBrush.get(),
3.0f
);
}
GameHud::Render yönteminde oyun penceresinin mantıksal boyutunu windowBounds
değişkeninde depolarız. Bu, GetLogicalSize
sınıfının yöntemini kullanır.
auto windowBounds = m_deviceResources->GetLogicalSize();
Kullanıcı arabirimi programlama için oyun penceresinin boyutunu elde etmek çok önemlidir. Pencerenin boyutu, bir DIP'in bir inçin 1/96'sı olarak tanımlandığı DIPs (cihazdan bağımsız pikseller) adlı bir ölçü biriminde verilir. Direct2D, çizim gerçekleştiğinde çizim birimlerini gerçek piksellere ölçeklendirir ve bunu yapmak için Windows inç başına nokta (DPI) ayarını kullanır. Aynı şekilde, DirectWritekullanarak metin çizdiğinizde, yazı tipinin boyutu için nokta yerine DIP'ler belirtirsiniz. DIP'ler kayan nokta sayıları olarak ifade edilir.
Oyun durumu bilgilerini görüntüleme
Uyarı ekranının yanı sıra, örnek oyun altı oyun durumunu temsil eden bir katmana sahiptir. Tüm durumlar, oyuncunun okuması için metin içeren büyük siyah bir dikdörtgen şeklinde arka plan içerir. Hareket-bakış denetleyicisi dikdörtgenleri ve nişangahlar, bu durumlarda etkin olmadıkları için çizilmez.
Katman, GameInfoOverlay sınıfı kullanılarak oluşturulur ve oyunun durumuyla uyumlu olacak şekilde hangi metnin görüntüleneceğini değiştirmemize olanak sağlar.
Katman durumunu ve eylemini
Katman iki bölüme ayrılır: Durum ve Eylem. Durum bölümü, Başlık ve Gövde dikdörtgenlerine daha ayrıntılı olarak ayrılmıştır. Eylemi bölümünde yalnızca bir dikdörtgen vardır. Her dikdörtgenin farklı bir amacı vardır.
-
titleRectangle
başlık metnini içerir. -
bodyRectangle
gövde metnini içerir. -
actionRectangle
, oyuncuyu belirli bir eylemi gerçekleştirmesi konusunda bilgilendiren metni içerir.
Oyun, ayarlanabilen altı eyalete sahiptir. Oyunun durumu, katmanın Durumu bölümü kullanılarak iletilir. Durumu dikdörtgenleri, aşağıdaki durumlara karşılık gelen bir dizi yöntem kullanılarak güncellenir.
- Yükleniyor
- İlk başlangıç/yüksek puan istatistikleri
- Düzey başlangıç
- Oyun duraklatıldı
- Oyun Bitti
- Oyun kazandı
Katman Eylem bölümü, GameInfoOverlay::SetAction yöntemi kullanılarak güncellenir, bu, eylem metninin aşağıdakilerden birine ayarlanmasına olanak tanır.
- "Yeniden oynatmak için dokunun..."
- Seviye yükleniyor, lütfen bekleyin ...
- "Devam etmek için dokunun ..."
- Hiç kimse
Uyarı
Bu yöntemlerin her ikisi de Oyun durumunu temsil etme bölümünde daha ayrıntılı olarak ele alınacaktır.
Oyunda neler olduğuna bağlı olarak, Durum ve Eylem bölüm metin alanları ayarlanır. Şimdi bu altı durum için katmanı nasıl başlatıp çizdiğimize bakalım.
Bindirmeyi başlatma ve çizme
Altı Durum durumunun birkaç ortak yanı vardır ve bu da ihtiyaç duydukları kaynakları ve yöntemleri çok benzer hale getirir. - Hepsi arka plan olarak ekranın ortasında siyah bir dikdörtgen kullanır. - Görüntülenen metin Başlık veya Gövde metnidir. - Metin Segoe UI yazı tipini kullanır ve arka dikdörtgenin üzerine çizilir.
Örnek oyunda katman oluşturulurken devreye giren dört yöntem vardır.
GameBilgisiÜzeri::GameBilgisiÜzeri
GameInfoOverlay::GameInfoOverlay oluşturucu, katmanı başlatır ve oyuncuya bilgi görüntülemek için kullanacağımız bit eşlem yüzeyini sürdürür. Oluşturucu, kendisine geçirilen ID2D1Device nesnesinden bir fabrika alır ve bu, katman nesnesinin çizim yapabileceği bir ID2D1DeviceContext oluşturmak için kullanılır. IDWriteFactory::CreateTextFormat
GameInfoOverlay::CreateDeviceDependentResources
GameInfoOverlay::CreateDeviceDependentResources, metnimizi çizmek için kullanılacak fırçaları oluşturma yöntemimizdir. Bunu yapmak için, geometrinin oluşturulmasını ve çizimini sağlayan bir ID2D1DeviceContext2 nesnesinin yanı sıra mürekkep ve gradyan mesh işleme gibi işlevler elde ediyoruz. Ardından, aşağıdaki kullanıcı arabirimi öğelerini çizmek için ID2D1SolidColorBrush kullanarak bir dizi renkli fırça oluştururuz.
- Dikdörtgen arka planları için siyah fırça
- Durum metni için beyaz fırça
- Eylem metni için turuncu fırça
DeviceResources::SetDpi
DeviceResources::SetDpi yöntemi pencerenin inç başına nokta sayısını ayarlar. DPI değiştirildiğinde ve bu nedenle yeniden ayarlanması gerektiğinde bu yöntem çağrılır; bu durum oyun penceresi yeniden boyutlandırıldığında meydana gelir. DPI güncelleştirildikten sonra, bu yöntemDeviceResources::CreateWindowSizeDependentResources çağırarak pencerenin her yeniden boyutlandırıldığında gerekli kaynakların yeniden oluşturulmasını sağlar.
GameInfoOverlay::CreateWindowsSizeDependentResources
GameInfoOverlay::CreateWindowsSizeDependentResources yöntemi, tüm çizimimizin gerçekleştiği yerdir. Aşağıda yöntemin adımlarının bir ana hattı yer alır.
Başlık, Metinve Eylem metnini kullanıcı arabirimi metninden ayırmak için üç dikdörtgen oluşturulur.
m_titleRectangle = D2D1::RectF( GameInfoOverlayConstant::SideMargin, GameInfoOverlayConstant::TopMargin, overlaySize.width - GameInfoOverlayConstant::SideMargin, GameInfoOverlayConstant::TopMargin + GameInfoOverlayConstant::TitleHeight ); m_actionRectangle = D2D1::RectF( GameInfoOverlayConstant::SideMargin, overlaySize.height - (GameInfoOverlayConstant::ActionHeight + GameInfoOverlayConstant::BottomMargin), overlaySize.width - GameInfoOverlayConstant::SideMargin, overlaySize.height - GameInfoOverlayConstant::BottomMargin ); m_bodyRectangle = D2D1::RectF( GameInfoOverlayConstant::SideMargin, m_titleRectangle.bottom + GameInfoOverlayConstant::Separator, overlaySize.width - GameInfoOverlayConstant::SideMargin, m_actionRectangle.top - GameInfoOverlayConstant::Separator );
m_levelBitmap
adlı bir Bit Eşlem, geçerli DPI dikkate alınarak, CreateBitmapkullanılarak oluşturulur.m_levelBitmap
, ID2D1DeviceContext::SetTargetkullanılarak 2D işleme hedefimiz olarak ayarlanır.Bit Eşlem, her piksel siyah yapılarak ID2D1RenderTarget::Clearkullanılarak temizlenir.
ID2D1RenderTarget::BeginDraw, çizimi başlatmak için çağrılır.
DrawText, karşılık gelen
m_titleString
kullanarak ,m_bodyString
vem_actionString
içinde depolanan metni uygun dikdörtgende çizmek için çağrılır.ID2D1RenderTarget::EndDraw,
m_levelBitmap
üzerindeki tüm çizim işlemlerini durdurmak için çağrılır.Geri dönüş olarak kullanmak üzere adlı
m_tooSmallBitmap
kullanılarak başka bir Bit Eşlem oluşturulur ve yalnızca görüntü yapılandırmasının oyun için çok küçük olup olmadığını gösterir.m_levelBitmap
içinm_tooSmallBitmap
üzerinde çizim işlemini yineleyin, bu kez yalnızcaPaused
dizesini gövdede çizin.
Şimdi tek ihtiyacımız olan altı katman durumunun metnini doldurmak için altı yöntem!
Oyun durumunu temsil etme
Oyundaki altı katman durumunun her biri, GameInfoOverlay nesnesinde karşılık gelen bir yönteme sahiptir. Bu yöntemler, oyuncuya oyunun kendisi hakkında açık bilgiler iletmek için katmanın bir varyasyonunu çizer. Bu iletişim, Başlık ve Gövde dizesiyle temsil edilir. Örnek, başlatıldığında ve GameInfoOverlay::CreateDeviceDependentResources yöntemiyle bu bilgi için kaynakları ve düzeni zaten yapılandırdığından, yalnızca katman durumuna özgü dizeleri sağlaması gerekir.
Katmanın Durumu bölümü, aşağıdaki yöntemlerden birine yapılan bir çağrıyla ayarlanır.
Oyun durumu | Durum belirleme yöntemi | Durum alanları |
---|---|---|
Yükleniyor | GameInfoOverlay::SetGameLoading |
Başlık Kaynakları Yükleme Gövde Yüklenme etkinliğini ima etmek için "." karakteri art arda yazdırılır. |
İlk başlangıç/yüksek puan istatistikleri | GameInfoOverlay::SetGameStats |
Başlık Yüksek Puan Bölüm Tamamlanan Düzeyler # Toplam Puan # Toplam Atışlar # |
Düzey başlangıç | GameInfoOverlay::SetLevelStart |
Başlık Düzeyi # Gövde Düzeyi hedef açıklaması. |
Oyun duraklatıldı | GameInfoOverlay::SetPause |
Başlık Oyun Duraklatıldı Gövde Yok |
Oyun Bitti | GameInfoOverlay::SetGameOver |
Başlık Oyun Bitti Body Tamamlanan Düzeyler Toplam Puan Toplam Atışlar Tamamlanan Düzeyler Yüksek Skor # |
Oyun kazandı | GameInfoOverlay::SetGameOver |
Başlık Kazandınız! İçerik Düzey Tamamlandı # Toplam Puan # Toplam Atış # Düzey Tamamlandı # Yüksek Puan # |
GameInfoOverlay::CreateWindowSizeDependentResources yöntemiyle, örnekte katmanın belirli bölgelerine karşılık gelen üç dikdörtgen alan bildirilmiştir.
Bu alanları göz önünde bulundurarak, duruma özgü yöntemlerden biri olan GameInfoOverlay::SetGameStatsyöntemine ve katmanın nasıl çizildiğine göz atalım.
void GameInfoOverlay::SetGameStats(int maxLevel, int hitCount, int shotCount)
{
int length;
auto d2dContext = m_deviceResources->GetD2DDeviceContext();
d2dContext->SetTarget(m_levelBitmap.get());
d2dContext->BeginDraw();
d2dContext->SetTransform(D2D1::Matrix3x2F::Identity());
d2dContext->FillRectangle(&m_titleRectangle, m_backgroundBrush.get());
d2dContext->FillRectangle(&m_bodyRectangle, m_backgroundBrush.get());
m_titleString = L"High Score";
d2dContext->DrawText(
m_titleString.c_str(),
m_titleString.size(),
m_textFormatTitle.get(),
m_titleRectangle,
m_textBrush.get()
);
length = swprintf_s(
wsbuffer,
bufferLength,
L"Levels Completed %d\nTotal Points %d\nTotal Shots %d",
maxLevel,
hitCount,
shotCount
);
m_bodyString = std::wstring(wsbuffer, length);
d2dContext->DrawText(
m_bodyString.c_str(),
m_bodyString.size(),
m_textFormatBody.get(),
m_bodyRectangle,
m_textBrush.get()
);
// We ignore D2DERR_RECREATE_TARGET here. This error indicates that the device
// is lost. It will be handled during the next call to Present.
HRESULT hr = d2dContext->EndDraw();
if (hr != D2DERR_RECREATE_TARGET)
{
// The D2DERR_RECREATE_TARGET indicates there has been a problem with the underlying
// D3D device. All subsequent rendering will be ignored until the device is recreated.
// This error will be propagated and the appropriate D3D error will be returned from the
// swapchain->Present(...) call. At that point, the sample will recreate the device
// and all associated resources. As a result, the D2DERR_RECREATE_TARGET doesn't
// need to be handled here.
winrt::check_hresult(hr);
}
}
GameInfoOverlay nesnesinin başlatıldığı Direct2D cihaz bağlamını kullanan bu yöntem, arka plan fırçasını kullanarak başlığı ve gövde dikdörtgenlerini siyahla doldurur. "Yüksek Puan" metnini beyaz metin fırçasını kullanarak başlık dikdörtgenine çizer ve oyun durumu bilgilerini içeren bir metni beyaz metin fırçasını kullanarak gövde dikdörtgenine çizer.
Eylem dikdörtgeni,
Herhangi bir durum için katman, aşağıdaki gibi GameMain::SetGameInfoOverlay yönteminde seçilir:
void GameMain::SetGameInfoOverlay(GameInfoOverlayState state)
{
m_gameInfoOverlayState = state;
switch (state)
{
case GameInfoOverlayState::Loading:
m_uiControl->SetGameLoading(m_loadingCount);
break;
case GameInfoOverlayState::GameStats:
m_uiControl->SetGameStats(
m_game->HighScore().levelCompleted + 1,
m_game->HighScore().totalHits,
m_game->HighScore().totalShots
);
break;
case GameInfoOverlayState::LevelStart:
m_uiControl->SetLevelStart(
m_game->LevelCompleted() + 1,
m_game->CurrentLevel()->Objective(),
m_game->CurrentLevel()->TimeLimit(),
m_game->BonusTime()
);
break;
case GameInfoOverlayState::GameOverCompleted:
m_uiControl->SetGameOver(
true,
m_game->LevelCompleted() + 1,
m_game->TotalHits(),
m_game->TotalShots(),
m_game->HighScore().totalHits
);
break;
case GameInfoOverlayState::GameOverExpired:
m_uiControl->SetGameOver(
false,
m_game->LevelCompleted(),
m_game->TotalHits(),
m_game->TotalShots(),
m_game->HighScore().totalHits
);
break;
case GameInfoOverlayState::Pause:
m_uiControl->SetPause(
m_game->LevelCompleted() + 1,
m_game->TotalHits(),
m_game->TotalShots(),
m_game->TimeRemaining()
);
break;
}
}
Artık oyun, oyun durumuna göre oyuncuya metin bilgilerini iletmenin bir yoluna sahiptir ve oyun boyunca görüntülenenleri oyuncuya değiştirmenin bir yolu vardır.
Sonraki Adımlar
Bir sonraki konu başlığında, denetim ekleme, oyuncunun örnek oyunla nasıl etkileşime geçtiğini ve girişin oyun durumunu nasıl değiştirdiğini inceleyeceğiz.