Şimdiye kadar ilk
yazımda host oluşturmayı öğrendik; ikinci
yazımda senkron, üçüncü
yazımda da asenkron olarak hostu aramayı ve hosta bağlanmayı öğrendik,
şimdi hosta bağlı olduğumuza göre sıra oyunu başlatmaya, oyunu oynamaya ve
oyunu sonlandırmaya geldi. Biraz önbilgi vererek bu konuya başlayalım.
Şu ana kadar yaptığımız her
şeyle oyun durumunu yada orijinal adıyla “NetworkSessionState”i hazır duruma
geçirdik. Multiplayer oyunlarda hostun ve oyuncuların; tüm oyuncuların giriş
yapmasını ve hostun oyuna başla komutunu vermesini, bekledikleri yere “lobby”
denir. Diğer bir değişle oyunumuz bu durumda NetworkSessionState.Lobby
durumundadır ve bu anda oyuncular oyuna başlayabilmek için durumlarını ready yapmalıdırlar
bu da oyuncuya(LocalNetworkGamer sınıfından türeyen oyuncuyu temsil eden
nesneye) ait IsReady özelliğini True yapmakla olur.
Bu yazımızın konusuna
gelirsek, oyunu başlattığımızda; ağın durumunun Lobby’den Playing (oynanıyor)
durumuna geçmesi gerekir. Bu da oturum nesnemizin StartGame metodoyla
sağlanacaktır.
Bu halledildikten sonra artık
çoklu ortamda, oyundasınız. Bu durumda bilgisayarlar arası haberleşme
yaptırmanız gerekmektedir. Bunu da bilgisayarlar arasında paket transferi ile
yapabilriz. Bir paketi PacketWriter türünden bir nesnenin Write() metodu ile
hazırlarız. Sonra bu paketi oyuncuyu temsil eden nesnenin SendData() metodu ile
göndeririz. Gelen paketi ise oyuncuya ait RecieveData() metoduyla ağdan çeker
alırız. Ve paketin içeriğini PacketReader türünden okuyucu nesnenin Read…..()
metodu ile çözeriz (okuruz). Buradaki ….
Kısmında türe göre metot seçilmelidir, örneğin fare koordinatları için
ReadVector2() gibi…
Tüm bu paket alış-verişi
işinde önemli olan nokta; Verilerin gönderiliş ve alınış türlerinin aynı olması
ve paket gönderme sırasının, paket alma sırasıyla uyumlu olmasıdır.
Önemli olduğunu düşündüğüm
için SendData() metodunun 2. parametresi hakkında bilgi vermek istiyorum metodu
birazdan kodda göreceksiniz;
2. parametre paketin gönderiliş
yöntemini belirler, SenderDataOptions enumuna dahil olan seçeneklerden,
None: paketin karşı tarafa
ulaşacağını garantilemez,
InOrder: paketleri belirli
bir sırayla yollar ama ulaşıp ulaşamayacağını garantilemez.
Reliable: paketler karşı
tarafa ulaşırlar (garantili), ama sıraları belirli değildir.
ReliableInOrder: paketler
sıralı olarak karşı tarafa ulaşır.(garantili)
Durum bu; buradan seçeceğiniz
özellik paketlerinizin türüne göre değişmelidir. Çok da önemli olmayan paketler
için en güvenli yolun kullanılması boşuna işlemcinin doldurulmasıdır.
Şimdi koda geçelim, eğer
açıklamalara göz attıysanız pek anlamakta sıkıntı çekmeyeceksiniz ama herhangi
bir durumda iletişime geçmekten çekinmeyin.
1. Adım tüm oyuncuları hazır
hale getirmek ve oyunu başlatmak:
AgIsleri.cs’de oyuncuları
hazır hale getiriyoruz.
public void
OyuncuyuHazırla()
{
/*
foraeach'in amacı aynı makinede oynayan oyuncuların
hepsini hazır etmektir
ama PC'de daima 1 local oyuncu
olacağı için Pc oyununda
foreach'e gerek yoktur.
*/
foreach
(LocalNetworkGamer oyuncu in oturum.LocalGamers)
oyuncu.IsReady = true;
}
Game1.cs den de oyuncunun
arayüzden hazırım demesini sağlıyoruz ben “R” (ready) tuşunu seçtim.
if
(Keyboard.GetState().IsKeyDown(Keys.R))
agYardimcisi.OyuncuyuHazirla();
AgIsleri.cs
ye geçelim. Eğer tüm oyuncular hazırsa host oyunu bu metod ile başlatmalı:
//eğer herkes hazır durumdaysa oyunu başlatacak
public void HerkesHazırsaBaslat()
{
if
(oturum.IsHost)
{
if
(osturum.IsEveryoneReady)
oturum.StartGame();
}
}
Şimdi bize bir de
oyunun(ağın) durumunu gösteren bir değişken lazım ki Game1.cs ye geçince bize
durumu anlatabilsin.
public NetworkSessionState OturumDurumu
{
get
{
if
(oturum == null)//
oturum yoksa
return
NetworkSessionState.Ended;
else
return
oturum.SessionState;
}
}
Şimdi Game1.cs ye geçip,
herkes hazırsa hosta oyunu başlattıracak kodu yazalım:
//loby durumundayken herkes hazırsa oyun başlar.
if
(agYardimcisi.OturumDurumu == NetworkSessionState.Lobby)
{
agYardimcisi.HerkesHazırsaBaslat();
}
Burada elimde olmayan
nedenlerden ötürü (birinin sahur yemeğini pişirmesi gerekiyor) yazımı kesiyorum.
Veri paketlerinin işlenmesini aynen kaldığım yerden devam ederek anlatacağım,
yukardaki öntanımlar bir sonraki yazı için aynen geçerlidir.