13 Ocak 2009 Salı
INETA EGE HIT
XNA’ de Modelin Hareketini Yönetmek
Ş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
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
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.
Ö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;
Modeli Yüklemek için LoadContent metodu içine eklememiz gereken bazı komut satırları var. Bunlardan
myModel = Content.Load
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
//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.
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.