Ogre Kütüphanesi Bölüm-9 Framelistener ve Tamponlanmamış Girdi-3
UstaDerslik Soru-Cevap Yararlı Araçlar
arama ikon
Diller
Türkçe Türkçe

bilgi UstaDerslik
Bu uyari kutusudur.
Tamam
Anasayfa
İletişim
Üyeler

Ogre Kütüphanesi Bölüm-9 Framelistener ve Tamponlanmamış Girdi-3

profil
OLENVERDGRUP
BEĞEN(0)
BEĞENME(0)
GÖRÜNTÜLENME(1457)
RAPOR ET
7. Şimdi de ışığımızı klavyemizdeki 1 tuşundan açıp kapatmayı deneyelim. Bu işlemi yaparken fareyeBasildi gibi bir değişken kurup bu değişkeni kontrol etmeyeceğiz. Farklı bir yol izleyeceğiz. Real türünde bir değişken kuracağız. Bu değişkeni event struct’unun timeSinceLastFrame değişkenini kullanarak düzenli olarak azaltacağız. Bu değişken sıfırdan küçükken ışığı açık kapata bileceğiz. Ama eğer ışık ayarlarında bir değişiklik olursa bu değişkenin değerini sıfırdan büyük bir değere eşitleyeceğiz. Bu sayede ışığın ayarını değiştirmeye çalıştığımızda bir süre değerin azalmasını beklememiz gerekecek. İlk olarak static ve real türünde, zamanlayici isimli değişkeni kurup sıfıra eşitliyoruz. Bu işlemi yapmak için tamponlanmamisGirdiIslemleri fonksiyonumuzun içine her şeyin altında “return ret;” satırının üstünde olacak şekilde şu satırları ekleyin:


//------------------------------ İKİNCİ IŞIK KONTROLÜMÜZ ------------------------------

// zamanlayici'mızı kuruyoruz:
static Ogre::Real zamanlayici = 0.0;


8. Şimdi zamanlayici’mızı FrameEvent struct’u evt’in timeSinceLastFrame değeri kadar her karede azaltmak için bir kod yazacağız. Dikkat edin ikisini eşitlemiyoruz. zamanlayici'yı timeSinceLastFrame kadar azaltıyoruz. Bu işlem için “-=” ifadesini kullanacağız. Her kare döngüsünde zamanlayici azaltılarak sıfırdan daha küçük bir değere eşitlenecek. Bu işlem için tamponlanmamisGirdiIslemleri fonksiyonumuzun içine her şeyin altında “return ret;” satırının üstünde olacak şekilde şu satırları ekleyin:


// zamanlayici'mızın değerini her karede düşürüyoruz:
zamanlayici -= evt.timeSinceLastFrame;


9. Şimdi if kontrolümüzü oluşturalım. zamanlayici eğer sıfırdan küçükse ve klavyenin 1 tuşuna basılmışsa if kontrolümüz çalışacak. mKeyboard nesnesi bizim klavyemizi temsil eden nesnedir. Bunun üzerinden isKeyDown fonksiyonuna ulaşacağız ve parametresine 1 tuşunu temsil eden KC_1 ifadesi yazacağız. zamanlayici ve bunun arasına “&&” işareti yazarak if kontrolümüzün şartını belirlemiş olacağız. Işığın ayarını değiştirmek için önceden yaptığımız işlemlerin aynısı yapacağız. if kontrolümüzün en sonunda da zamanlayici’yı 0.5 değerine eşitleyeceğiz. Bu bize yaklaşık yarım saniye kazandıracak. FrameListener sınıfı birkaç kare boyunca 0.5 değerini düşürerek sıfırdan daha küçük bir değer haline getirene kadar if kontrolümüz çalışmayacak. Bu işlemler için tamponlanmamisGirdiIslemleri fonksiyonumuzun içine her şeyin altında “return ret;” satırının üstünde olacak şekilde şu satırları ekleyelim:


// Eğer zamanlayicimiz sıfırdan küçükse ve 1 tuşuna basılmışsa if kontrolümüz çalışacak:
if ((zamanlayici < 0.0f ) && mKeyboard->isKeyDown(OIS::KC_1)) {
// Önceki ışık kontrolünde yaptığımız işlemi tekrarlıyoruz:
Ogre::Light* isik = mSceneMgr->getLight("noktasalIsik");
isik->setVisible(! isik->isVisible());

// Zamanlayicimızın değerini yükseltiyoruz. 0,5 değeri yaklaşık yarım saniyeye denk geliyor:
zamanlayici = 0.5; }


10. Şimdi Ninja nesnemizi IJKL-UO tuşlarıyla hareket ettirmeye Shift+J ve Shift+L tuşlarıyla kendi etrafında döndürme işlemine sıra geldi. Öncelikle hareket ve döndürme hızımızı belirleyen iki değişken tanılıyoruz. Bu değişkenleri tamponlanmamisGirdiIslemleri fonksiyonumuzun içine her şeyin altında “return ret;” satırının üstünde olacak şekilde ekleyelim:


//-------------------------------- NİNJA'NIN KONTROLÜ ---------------------------------

// Hareket ve döndürme hızımızı belirleyecek iki değişken tanımlıyoruz:
static Ogre::Real dondurmeKatsayisi = 0.13; static Ogre::Real hareketKatsayisi = 250;


11. Teorik derste TS_WORLD ve TS_LOCAL kodlarından bahsetmiştik. Aslında teorik derste bahsettiğimiz konu doğru, ama tersinden bahsetmişiz. Döndürme işlemi yaptıktan sonra ninja nesnemizi örneğin ileriye doğru götürmeye çalıştığımızda, yan yan gidiyor. TS_LOCAL kodu burada lazım oluyor. Bunu sebebi, OGRE’nin kodlama sisteminde Entity nesnelerine, ki ninja nesnemizde bir Entity nesnesi, her karede hareket işlemi yapmak söz konusu olduğunda, SN’lerine doğrudan işlem yapamıyoruz. Ama döndürme işlemi yapmak istediğimizde doğrudan SN’sine ulaşıp döndürebiliyoruz. Hareket işlemi için bir vektör tanımlayacağız. Tüm hareket işlemlerini bu vektöre uygulayacağız. Sonra tanımladığımız bu vektörü ninja’nın SN’siyle, TS_LOCAL kodunu da kullanarak, çarpma işlemine sokup, ninja’nın istediğimiz gibi hareket etmesini sağlayacağız. Bu işlem öteleme adını alıyor. ninja’nın SN’sinin konum vektörünü başka bir vektörle öteleyeceğiz.

Şimdi ninja nesnemizin hareketlerini kontrol edecek olan vektörümüzü tanımlayalım. Adı otelemeVektoru olacak. Değerini Vector3 sınıfındaki ZERO vektörüne eşitliyoruz. Yani otelemeVektoru = (0, 0, 0) olacak. Aynı zamanda ZERO vektörü static olarak tanımlanmış bir vektördür. Yani ilk kareden sonra her karede ninjayı ilerletmiş olsak bile otelemeVektoru sürekli sıfır vektörü olarak yenilenmeyecek. tamponlanmamisGirdiIslemleri fonksiyonumuzun içine her şeyin altında “return ret;” satırının üstünde şu satırları ekliyoruz:


// Hareket işlemleri için kullanacağımız otelemeVektoru'nü kuruyoruz:
Ogre::Vector3 otelemeVektoru = Ogre::Vector3::ZERO;


12. Ardı ardına birçok if kontrolü kuracağız. Öncelikle otelemeVektoru’nü ileri ve geri hareket ettirecek if kontrolünü kuralım. Önceki derslerden hatırlarsanız, tam karşımız Z ekseni oluyordu. Z ekseni orijinden bize doğru geldikçe arttığından dolayı ilerlemek için Z ekseninde negatif değerlere gitmeliyiz. Bu işlemi gerçekleştirmek için I tuşuna basıldığında otelemeVektoru’müzün z değerini, hareketKatsayisi kadar azaltacağız. Geri gitmek içinse K tuşuna basıldığında otelemeVektoru’müzün z değerini, hareketKatsayisi kadar arttıracağız. tamponlanmamisGirdiIslemleri fonksiyonumuzun içine her şeyin altında “return ret;” satırının üstünde şu satırları ekliyoruz:


// İleri
if (mKeyboard->isKeyDown(OIS::KC_I)) {
otelemeVektoru.z -= hareketKatsayisi;
}
// Geri if (mKeyboard->isKeyDown(OIS::KC_K)) {
otelemeVektoru.z += hareketKatsayisi;
}


13. Şimdi iç içe iki if kontrolü kuracağız. Dıştaki J tuşuna basılıp basılmadığını, içteki sol Shift tuşuna basılıp basılmadığını kontrol edecek. İç kısımdaki if kontrolü, eğer sol Shift tuşuna basılmışsa ninja nesnesini Y ekseni etrafında dondurmeKatsayisi’nın 5 katı kadar döndürecek. Eğer sol Shift tuşuna basılmamışsa, yani sadece J tuşuna basılmışsa, otelemeVektoru’müzün x değeri hareketKatsayisi kadar azalacak. Bu işlemleri L tuşu için de tekrarlayacağız ama bu sefer otelemeVektoru’muzun x değeri hareketKatsayisi kadar artacak. tamponlanmamisGirdiIslemleri fonksiyonumuzun içine her şeyin altında “return ret;” satırının üstünde şu satırları ekliyoruz:


// Sola Hareket ve Sola Dönme
if (mKeyboard->isKeyDown(OIS::KC_J))
{
if(mKeyboard->isKeyDown( OIS::KC_LSHIFT ))
{
mSceneMgr->getSceneNode("NinjaDugumu")->yaw(Ogre::Degree(dondurmeKatsayisi * 5));
} else {
otelemeVektoru.x -= hareketKatsayisi;
} }

// Sağa Hareket ve Sağa Dönme
if (mKeyboard->isKeyDown(OIS::KC_L))
{
if(mKeyboard->isKeyDown( OIS::KC_LSHIFT ))
{
mSceneMgr->getSceneNode("NinjaDugumu")->yaw(Ogre::Degree(-dondurmeKatsayisi * 5));
} else {
otelemeVektoru.x += hareketKatsayisi;
} }


14. Son olarak UO tuşlarıyla ninja nesnemizi Y ekseninde yükseltip-alçaltma işlemini yapalım. Bu işlemin ileri-geri hareketten hemen hemen hiçbir farkı yok. Yine bir if kontrolü oluşturacağız. Eğer U tuşuna basılırsa otelemeVektoru’müzün y değeri hareketKatsayisi kadar artacak. İkinci if kontrolümüzde de eğer O tuşuna basılırsa otelemeVektoru’muzun y değeri hareketKatsayisi kadar azalacak. Tuş kontrol işlemleri bu kadar. En son otelemeVektoru’müzü ninja nesnemizin SN’sine uygulayacağız. mSceneMgr nesnesinden getSceneNode fonksiyonunun parametresine “NinjaDugumu” yazarak ninja nesnemizin SN’sine ulaşacağız. Bunun üzerinden translate komutunu kullanarak otelemeVektoru’müzü ninja’mızın SN’sinin konum vektörüne uygulayacağız. translate fonksiyonu ilk parametresindeki vektör değerini nesnenin konum vektörüyle çarpar. translate fonksiyonunun ilk parametresine direk otelemeVektoru’nü yazmayacağız. Bunun sebebine teorik derste değinmiştik. Yalın halde otelemeVektoru’nu kullanırsak FPS değeri kadar otelemeVektorumuz bir saniye içinde defalarca ninja’nın SN’siyle çarpılır. Eğer otelemeVektoru’nü evt’in timeSinceLastFrame ile çarparsak, örneğin bir saniye boyunca 30 birim ilerlemesi için her karede 5 birim ilerlemesi gerekiyorsa, timeSinceLastFrame bu işlemi gerçekleştirir. Bunu anlamada güçlük çekiyorsanız ilk parametreye timeSinceLastFrame ile çarpmadan direk otelemeVektoru’nu yazıp uygulamayı çalıştırın. IJKL-UO tuşlarından birine bastığınızda oluşan sorunu göreceksiniz. translate fonksiyonunun ikinci parametresine de TS_LOCAL kodunu giriyoruz. Bu sayede otelemeVektoru, ninja’nın SN’sinin bağlı olduğu mSceneMgr’nin SN’sine uygulanmak yerine, direk ninja’nın SN’sine uygulanıyor. tamponlanmamisGirdiIslemleri fonksiyonumuzun içine her şeyin altına “return ret;” satırının üstüne şu satırları ekliyoruz:


// otelemeVektoru'ne yapılan tüm işlemlerin Ninja'nın SceneNode'sine uyguluyoruz:
mSceneMgr->getSceneNode("NinjaDugumu")->translate(otelemeVektoru * evt.timeSinceLastFrame, Ogre::Node::TS_LOCAL);


Projeyi derleyip çalıştırabilirsiniz. IJKL-UO tuşlarını kullanarak ninja’yı hareket ettirebilirsiniz. Shift+J ve Shift+L tuş ikilileriyle ninja’yı döndürebilirsiniz.

C. BİTİRİRKEN


Şuan temel olarak FrameListener’ı ve Tamponlanmamış Girdi (Unbufferred Input) işlemini tanımış bulunmaktasınız. Eğer bu projeyi oluşturmakta farklı sorunlar yaşıyorsanız kendi kodlarınızı Kaynak Kodu ile karşılaştırabilirsiniz.



Kod
Kalın
Vurgu
Resim
Video
Url
CEVAPLA
Tüm Hakları Saklıdır. ©Arleone 2013-2014 UstaDerslik






Giriş
Şifremi Unuttum...
Şifre Talep
  Kuralları Kabul Ediyorum.
Kaydol