Makale Özeti

XNA ile oyun geliştirme aşamasında görsellik açısından çoğu zaman efekt kullanmak durumunda kalırız. Bu efeklerin yaratılması konusunda bazı motorlar bulunmakta.Mercury Particle Engine 3.1 ile istediğimiz efekti yaratabilir ve uygulamalarımızda kullanabiliriz

Makale

XNA ile Efekt yaratmak

 XNA ile oyun geliştirme aşamasında görsellik açısından çoğu zaman efekt kullanmak durumunda kalırız.Geliştirdiğimiz oyun türüne göre örneğin; bir silahtan çıkan kurşuna bir efekt verebilir veya iki araba düşünelim bunların çarpışması üzerine oluşacak patlama için bir efekt yaratabiliriz.Bu efeklerin yaratılması konusunda bazı motorlar bulunmakta.Mercury Particle Engine 3.1 ile istediğimiz efekti yaratabilir ve uygulamalarımızda kullanabiliriz tabiki ilgili referansları vererek.Bu yazımda basit olarak efektlerin nasıl yaratıldığı konusunda biraz araştırmalarım konusunda XNA bize oldukça kolaylıklar sağlamaktadır.Basit iki class yaratarak istediğimiz efekti yaratabiliyoruz.

 Basit iki class yaratarak istediğimiz efekti yaratabiliyoruz demiştik biraz bu classlardan bahsedelim.Particle.cs sınıfımızı efektimiz içindeki nesneler olarak düşünebiliriz bir efektin içinde yüzlerce nesne olabilir ve bu nesnelerin hepsini bir efekt yaratmak istediğimizde yönetmek durumunda kalıyoruz.

Particle.cs

Her particle nesnemiz temel bazı özellikleri taşımak zorunda burada dikkati çeken bir kısaltma var TTL(Time to live) yarattığımız her nesneye oyunumuz çalıştığı süre içinde bir yaşam süresi veriyoruz.Particle nesnemiz bu süre boyunca yaşıyor daha sonra yok ediliyor.

 Methodlarda neler olduğuna bakarsak;

 public void Update()
        {
            TTL--;
            Position += Velocity;
            Angle += AngularVelocity;
        }

Update methodunda TTL süresini azaltıyoruz ve nesnemizin pozisyonunu değiştiriyoruz.

public void Draw(SpriteBatch spriteBatch)
        {
            Rectangle sourceRectangle = new Rectangle(0, 0, Texture.Width, Texture.Height);
            Vector2 origin = new Vector2(Texture.Width / 2, Texture.Height / 2);
            spriteBatch.Draw(Texture, Position, sourceRectangle, Color,
                Angle, origin, Size, SpriteEffects.None, 0f);
        }

Draw methodunda da klasik nesnemizi ekrana çizdirme işlemlerini yaptırıyoruz.

ParticleEngine.cs

Burada da ilk göze çarpan “EmitterLocation” nedir geliyor akıllara bu da aslında yaratacağımız efektin nereden başlayarak yayılmasını sağlayan Vector2 tipinde bir özellik.Biz uygulamamızda bunu faremizin bulunduğu noktayı vereceğiz. 

Methodları incelersek Draw methodunda efektimizde kullandığımız particle nesnelerini ekrana çizdiriyoruz.GenerateNewParticles methoduyla da az önce yazmış olduğumuz Particle classımızdan efektimiz için gerekli nesneleri üretiyoruz.Update methoduyla da bu nesnelere hareket sağlıyoruz.GenerateNewParticle methodunu incelersek;

private Particle GenerateNewParticle()
        {
            Texture2D texture = textures[random.Next(textures.Count)];
            Vector2 position = EmitterLocation;
            Vector2 velocity = new Vector2(
                                    1f * (float)(random.NextDouble() * 2 - 1),
                                    1f * (float)(random.NextDouble() * 2 - 1));
            float angle = 0;
            float angularVelocity = 0.1f * (float)(random.NextDouble() * 2 - 1);
            Color color = new Color(
                        (float)random.NextDouble(),
                        (float)random.NextDouble(),
                        (float)random.NextDouble());
            float size = (float)random.NextDouble();
            int ttl = 20 + random.Next(40);
 
            return new Particle(texture, position, velocity, angle, angularVelocity, color, size, ttl);
        }

Görüldüğü gibi her üretilen particle nesnesine bir hareket hızı (velocity) veriliyor ayrıca yine random nesnemizle particle nesnelerini değişik renklerde,değişik boyutlarda ve değişik yaşam süreleriyle üretiyoruz.

Yazdığımız sınıfları kullanma konusuna gelince Game1.cs inceleyelim.

public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        ParticleEngine particleEngine;
 
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }
 
        protected override void Initialize()
        {
            base.Initialize();
        }
 
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            List<Texture2D> textures = new List<Texture2D>();
            textures.Add(Content.Load<Texture2D>("circle"));
            textures.Add(Content.Load<Texture2D>("star"));
            textures.Add(Content.Load<Texture2D>("diamond"));
            particleEngine = new ParticleEngine(textures, new Vector2(400, 300));
        }
 
        protected override void UnloadContent()
        {
 
        }
 
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            particleEngine.EmitterLocation = new Vector2(Mouse.GetState().X, Mouse.GetState().Y);
            particleEngine.Update();
            base.Update(gameTime);
        }
 
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);
            particleEngine.Draw(spriteBatch);
            base.Draw(gameTime);
        }
    }

Görüldüğü gibi LoadContent() methodunda efektimiz için gerekli görselliği sağlayacak olan particle nesnelerimizi yükledik ve bir particle engine ürettik.Update methodunda öncelikle EmitterLocation özelliğimizi faremizin bulunduğu indeks ile set ettik daha sonra update() methodumuzu çağırdık.Draw methodunda ise particle engine draw methodunu çağırdık böyle tüm particle nesnelerimiz ekrana çizdirildi.

 XNA ile efektlerin nasıl yaratıldığı ve kullanıldığı konusunda bilgi sahibi olduk.Örnek Uygulamanın kodlarına buradan erişebilirsiniz veya uygulamanın silverlight versiyonunu görmek için buraya tıklayabilirsiniz.