13 Ocak 2009 Salı

INETA EGE HIT



Dokuz Eylül Üniversite' sinin ev sahipliğini yaptığı 2 gün süren Ineta eğitimi tamamalandı.

Çoğunluğu bilişim sektöründeki firmalarda çalışan geliştricilerin oluşturduğu etkinliğe üniversite ve lise öğrencilerinden yoğun talep vardı. Katılımcılar hallerinden pek memnundu. Daron Yöndem' in şiir gibi kod yazdığı söylendi. Ee doğru söze ne denir.

Umarız en kısa sürede yeni etkinliklerle Daron Yöndem' i tekrar aramızda görürüz.

Kendisine Dokuz Eylül Üniversitesi adına teşekkür ediyoruz.


**Detaylı bilgi için Daron Yöndem' in adresini ziyaret edebilirsiniz.



XNA’ de Modelin Hareketini Yönetmek

Modelin nasıl hareket ettiğinden bahsetmiştim ama çoğumuzun aklına bu modelin hareketi kendiliğinden oluyor. Oyuncu modeli hareket ettirmek istediğinde bunu kod olarak nasıl yapacağımız sorusu gelebilir. Bu sorunun cevabını yine Update metoduna ekleyteceğimiz satırlarda bulacağız. Unutmamız gereken önemli husulardan biride Game1.cs sınıfı içindeki metotların kullanımıdır. LoadContent metodu oyu ilk çalıştırıldığında gerekli yüklemeleri yapar ve sadece bir kere çağrılır. Draw ve Update metotları ise FPS değeri kadar çağrılır.

Şimdi ekleyeceğimiz satırlarla modelimiz sağa, sola, yukarı ve aşağı yönlerine kullanıcın verdiği talimatlarla hareket ediyor. Modelimiz sağ ok ile sağa, sol ok ile sola,...., hareket etmektedir.

Tanımlamamız gereken iki adet float tipinde değişken bulunmaktadır. Bunlardan forpozitionX değişkeni modelin X ekseninde hareketini sağlamak için tanımlanmıştır. Sağa ya da sola gitmesini sağlar. forpozitionY değişkeni ise modelin Y ekseninde aşağıya da yukarıya hareketini sağlamak için tanımlanmıştır.

if (keyboardState.IsKeyDown(Keys.Left): sol yönü belirten oka basılıp basılmadığını kontrol eder.

Eğer bu oka basıldıysa modelin hareketi sola olmalıdır. Bu durumda forpozitionX değişkeninin değeri azaltılır. Ben kullandığım modelin boyutuna uygun olsun diye 5.0f kullandım siz bu değeri modelinize uygun oalrak ayarlayabilirsiniz. Dikkat etmemiz gereken bu değerin 0.0f ve bunun altına düşmemisidir. Bu nedenle azaltma işleminden önce bu değişkenin değeri kontrol edilir.

if (keyboardState.IsKeyDown(Keys.Right)): sağ yönü belirten oka basılıp basılmadığını kontrol eder.

Bu oka basıldıysa modelin hareketi sağa olmalıdır. Bu durumda forpozitionX değişkeninin değeri arttırılır.

if (keyboardState.IsKeyDown(Keys.Up)): yukarı yönü belirten oka basılıp basılmadığını kontrol eder.

Eğer bu oka basıldıysa modelin hareketi yukarı olmalıdır. Bu durumda forpozitionY değişkeninin değeri arttırılır.

if (keyboardState.IsKeyDown(Keys.Down)): aşağı yönü belirten oka basılıp basılmadığını kontrol eder.

Eğer aşağıya hareketi sağlayan oka basıldıysa modelin hareketi aşağıya olmalıdır. Bu durumda forpozitionY değişkeninin değeri azaltılır. Ancak bu değerin 0.0f ve bunun altına düşmemisi gerekir. Bu nedenle azaltma işleminden önce bu değişkenin değeri kontrol edilir.


float forpozitionX = 0.0f;
float forpozitionY = 0.0f;



protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();

// TODO: Add your update logic here
//modeli hareket ettiren kodlar
KeyboardState keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyDown(Keys.Left))
{
if(forpozitionX>5.0f)
forpozitionX -= 5.0f;
modelPosition = new Vector3(forpozitionX, forpozitionY, 0.0f);
}
if (keyboardState.IsKeyDown(Keys.Right))
{
forpozitionX += 5.0f;
modelPosition = new Vector3(forpozitionX, forpozitionY, 0.0f);
}
if (keyboardState.IsKeyDown(Keys.Up))
{
forpozitionY += 5.0f;
modelPosition = new Vector3(forpozitionX, forpozitionY, 0.0f);
}
if (keyboardState.IsKeyDown(Keys.Down))
{
if(forpozitionY>5.0f)
forpozitionY -= 5.0f;
modelPosition = new Vector3(forpozitionX, forpozitionY, 0.0f);
}
base.Update(gameTime);
}

XNA ‘de 3 Boyutlu Modeli Hareket Ettirmek

XNA’ de 3 boyutlu bir modeli nasıl ekleyeceğimiz ile ilgili yazımda “modelRotation” adlı bir değişkenden bahsetmiştim. Şimdi bu değişkende bazı değişiklikler yaparak modelimizi hareket ettirelim. “XNA Framework Content Pipeline” kullanarak dokularını eklediğimiz model nasıl hareket edecek?
Bunun için yapmamız gereken tek şey Update metosu içine tek satır kod eklemektir. Evet bir modeli tek satır bir kod ile döndürebileceğiz. XNA kütüphanesinin en büyük artılarından biride budur, az satırda kodla çok işler başarmanızı sağlar.
Şimdi Update metonunun içine bu satırı yazalım:



Draw metodu içindeki CreateRotationY metodu (Modelin Y ekseninde dönmesini sağlıyor.)yerine CreateRotationX metodunu kullanırsanız model X ekseninde döner, CreateRotationZ kullanırsanız hareketini Z ekseninde yapar.


XNA’ de 3 Boyutlu Model Ekleme

XNA kütüphanesini kullanarak oluşturduğunuz bir projeye 2 boyutlu bir nesne eklemek için gerekli olan tanımlamalar; öncelikle iki boyutlu resmimizi çizmemizi sağlayacak olan bir SpriteBatch nesnesi, bu resmimizin oyuna yüklenmesini sağlayacak olan bir Texture2D verisi ve resmin konumunu belirteceğimiz Vector2 yapısında tanımlanmış olan bir veriydi.

3 Boyutlu model eklemede işler biraz değişiyor. Herşeyden önce artık model kavramı işin içine giriyor. Artık mesh olarak da bahsedilen doku kavramı işin içine giriyor. Modele farklı açılardan baktığımızda önceki açıda göremediğimiz kısımlarını görürüz. Bu kısımlar aslında o modeli oluştuturken farklı çizilen resimlerin bir araya getirilmesinde kaynaklanıyor. Bu kısımları modelimizin dokuları olarak düşünebiliriz.

Bu yazımda size 3 boyutlu bir modeli eklemek için nelerin gerekli olduğundan ve projemizde yapmamız gerekenlerden bahsedeceğim.

1.) Gerekli Tanımlamalar

Öncelikle modelimiz ile ilgili tutacak bir Model nesnesi tanımlamalıyız.

Bu tanımlamayı Game1.cs sınıfımız içinde sınıf tanımlamamızın hemen içine yazalım. Ardından ekran oranı bilgilerini tutacak olan float türünde “aspectRatio” adlı bir değişken tanımlayalım. Şimdi bu modelimizi farklı açılardan da görmemizi sağlayan kameramız için modeli hangi açıdan görmek istiyorsak bu bilgileri bverebileceğimiz Vector3 tipinde bir değişken tanımlayalım. Bu değişkenimizin adı da “cameraPosition” olsun. “projectionValue” değişkeni modeli ne kadarlık bir açıdan görmek istediğimizi belirler. Bu değeri arttırdığımızda model daha uzaktan gelir, azalttığımızda model sanki daha yakınmış gibi görünür.

public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
Model myModel;
//projection icin gorus acini belirleyecek degisken.
float aspectRatio;
//kamera için
Vector3 cameraPosition;
float projection_value=30.0f;
2.) Modeli Yüklemek

Modeli Yüklemek için LoadContent metodu içine eklememiz gereken bazı komut satırları var. Bunlardan

myModel = Content.Load("Models/model1 ");

Var olan modeli dokularıyla birlikte eklememizi sağlar. Dokularıyla ilgili bir kod yazmadığımız halde nasıl oluyorda model dokularını bulabiliyor?

“fbx” uzantılı modellerimizin dosyaları mevcut. Bu modelleri projemize eklediğimizde modele tıkladığınızda .NET ortamında bu dosya açılır. Dosyanın içerisine baktığınızda her dokuyu aradığı “RelativeFilename” tanımlıdır. Burda dokunun bulunduğu dizinin adresi yer almaktadır.
aspectRatio değeri aşağıdaki komut satırında görüldüğü gibi hesaplanır.

Kameranın yerini belirlemekte kullanacağımız “cameraPozition” değişkeninin ilklemesini de aşağıdaki satırdaki gibi yapıyoruz. Burdaki ilk parametre “right” ı belirten x eksenini ikinci parametre “up” ı belirten y eksenini ve üçüncü parametre “look” ı belirten eksenini ifade etmektedir. Eğer ikinci argümanı 10.f yerine 5000.f oalrak değiştirirseniz cisminizin görünüşünde değişiklik olur. Üst kısmını daha iyi görebilirsiniz.

cameraPosition = new Vector3(0.0f, 10.0f, 5000.0f);

protected override void LoadContent()
{
//modeli yukle
myModel = Content.Load("Models/model1");
//bakis acini belirle,cismin ne kadar darlık ya da genislikte gorulecegidir
aspectRatio = (float)graphics.GraphicsDevice.Viewport.Width /
(float)graphics.GraphicsDevice.Viewport.Height;
// view matrisin icin kameranin yerini belirliyorsun
cameraPosition = new Vector3(0.0f, 10.0f, 5000.0f);

}

3.) Modeli Çizdirmek


İki boyutşu bir resim çizdirirken yapmamız gerekn 3 satır kod yazmaktı. Ancak 3 boyutlu modelde bu iş biraz daha karışık. Çünklü bu kez çizmemiz gerekende dokular ve her bir doku üzerindeki efektler var. Yani bizim ihtiyacımız olan iki adet içi içe döngü. Dıştaki dökğ modelin içerdiği dokuları çizdirecek içteki döngü ise çizilecek olan doku üzerine tanımlanan efektleri ekleyecek.


Öncelikle modelimizin aslında hareketini de sağlayacan “modelRotation” değişkenini tanımlıyoruz. Bu değişkenin değerinde oynamalar yaptığınızda modelimizin biraz daha sağa dönük durduğunu görebilrsiniz.


effect.EnableDefaultLighting();


Yukarıdaki satır dokular üzerindeki ışıklandırmayı sağlar.


Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up);

ile modelimize kameranın bakacağı açıyı belirliyoruz.

mesh.Draw();

Bu satır ile bir dokuyu çizmiş oluyoruz.

float modelRotation = 0.0f;


protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);

// TODO: Add your drawing code here

//world matrisi icin gerekli olan tanimlamalar
Matrix[] transforms = new Matrix[myModel.Bones.Count];
myModel.CopyAbsoluteBoneTransformsTo(transforms);

//bu asamada modeli cizmeye baslioruz
//model icin birden fazla doku olabilir bu yuzden bir dongu kullanioruz

foreach (ModelMesh mesh in myModel.Meshes)
{

//her doku icinde belirli efektler olabilir bunlar icinde bir dongu kullan
//bu dongu icinde gerekli olan yerlere kamerayi tut.
foreach (BasicEffect effect in mesh.Effects)
{
//dokular üzerindeki isiklandirmayi sagla
effect.EnableDefaultLighting();

effect.World = transforms[mesh.ParentBone.Index] * Matrix.CreateRotationY(modelRotation) *
Matrix.CreateTranslation(modelPosition);
effect.View = Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up);

//projectiondaki bu 45 derecelik aciyi modeli ne kadar yakindan gorecegini belirler
//bu aci ne kadar büyürse model sana o kadar uzak olur
effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(projection_value),
aspectRatio, 1.0f, 10000.0f);
}//end of inner foreach loop

//simdi bu dokuyu cizdir

mesh.Draw();
}//end of outer foreach loop


base.Draw(gameTime);

}

Şimdi yapmanız gereken internetten bir modeli ve dokularını bulup bunları projenize ekleyip bu satırlarla birlikte bu modelin ekranda görünmesini sağlamak. Kolay gelsin :)

NOT: Modelinize göre "projection_value" değeriyle oynarsanız daha iyi sonuçlar elde edebilrsiniz. Bazı modeller 30.0f değerinde görülebiliyorken bazı modelleri algılayamayabiliyorusunuz. Bu durumda bu değeri küçültmeniz gerekmektedir, eğer model bu değerde çok büyük görünüyorsa bu kez bu değeri azaltmanızı öneririm.