Arşiv

Etiketlenen yazılar readonly

C# ile Geçici Dosya (Temporary File) oluşturma sınıfı yazalım

13 Temmuz 2011 Yorum yapılmamış

Projelerimizde dosya sistemi üzerinde geçici olarak dosya oluşturma ve işimiz bittiğinde silme ihtiyacı hissedebiliriz.

Bu yazıyı okumadan önce Hem benzersiz hem de geçici dosya oluşturmanın en kolay yolu ve C# ile Geçici Dosya Oluşturmak başlıklı yazılarımı okumanızı öneririm.

Bu linkte bulduğum yöntemi çok kullanışlı buldum ve sizler (aynı zamanda kendim) için türkçeleştirdim;

public class TempFile : IDisposable
{
	public TempFile() : this(string.Empty)
	{ }

	private readonly string _tmpfile;

	public TempFile(string extension)
	{
		_tmpfile = Path.GetTempFileName();

		if (!string.IsNullOrEmpty(extension))
		{
			string newTmpFile = _tmpfile + extension;

			/// Yeni bir geçici dosya oluşturulur
			File.Create(newTmpFile, 0);
			/// Eski geçici dosya silinmediyse, silinir.
			File.Delete(_tmpfile);

			/// Yeni oluşturulan geçici dosya kullanıma hazır!
			_tmpfile = newTmpFile;
		}
	}

	public string FullPath
	{
		get { return _tmpfile; }
	}

	void IDisposable.Dispose()
	{
		if (!string.IsNullOrEmpty(_tmpfile) && File.Exists(_tmpfile))
		{
			File.Delete(_tmpfile);
		}
	}
}

Kullanımına örnek;

using(TempFile tmp = new TempFile(".dat")) /// dat uzantılı bir geçici dosya oluşturuluyor
{
	/// FullPath özelliğinden geçici dosyanın yolu ve dosya adı alınabilir;
	string filename = tmp.FullPath;
}

XNA ile Hareketli Arkaplan

29 Haziran 2011 Yorum yapılmamış

Bu yazımı okumadan önce XNA ile Oyun Programlama kategorisindeki diğer makalelerimi okumanızı tavsiye ederim.

Birçok oyunda arkaplan görselinin yavaşça kaydığını görmüşüzdür. Bu tarz bir etkiyi kendi oyunlarımızda nasıl sağlayacağımızı bu yazımda inceliyor olacağım.

Her zamanki gibi öncelikle görselleri paylaşarak başlıyorum;

XNA ile Oyun Programlama - Uzay Arkaplan Resmi XNA ile Oyun Programlama - Uçak Resmi

Öncelikle sınıf seviyesinde birkaç değişken/sabit (readonly, const) ile oyun penceremizin özelliklerini ayarlayalım;

private const int PENCERE_GENISLIK = 800;
private const int PENCERE_YUKSEKLIK = 600;

private readonly Color PENCERE_ARKAPLAN = Color.Black;

Oyun sınıfının constructor‘ında ilgili sabitleri kullanalım;

graphics.PreferredBackBufferWidth = PENCERE_GENISLIK;
graphics.PreferredBackBufferHeight = PENCERE_YUKSEKLIK;

Oyun projemize, Uzay ve Ucak isimli iki tane sınıf (class) ekleyelim. Böylece arkaplan’da kayacak uzay görseli ile ilgili işleri Uzay sınıfında, klavye ile yöneteceğimiz uçak ile ilgili işleri de Ucak sınıfında gerçekleştirebileceğiz.

Ucak.cs dosyasında yeralan Ucak sınıfının yapacağı işler çok basit;

public class Ucak
{
	public Vector2 Position;
	public readonly Vector2 Size;

	public Texture2D Texture { get; private set; }

	public Ucak(Texture2D Texture)
	{
		this.Texture = Texture;
		this.Size = new Vector2(Texture.Width, Texture.Height);
	}
}

Uzay.cs dosyasında yeralan Uzay sınıfı ise, kendi Update() ve Draw() method’larına sahip olacak. Draw() method’unda sürekli arkaplan görselini kaydırarak oyun penceresine çizdirecek.

Bunu yapabilmek için, SpriteBatch sınıfından bir instance’a ihtiyaç duyacağız.

Uzay sınıfının constructor‘ında ihtiyacımız olacak SpriteBatch tipinden bir parametre alacak ve sınıf seviyesinde bir değişkende saklayacağız;

public class Uzay
{
	private readonly Texture2D _Texture;
	private readonly Texture2D _TextureSecond;

	private float _Position = 0f;

	private readonly int _Width;

	private readonly SpriteBatch _SpriteBatch;

	public Uzay(Texture2D Texture, SpriteBatch SpriteBatch)
	{
		this._SpriteBatch = SpriteBatch;

		this._Texture = Texture;
		this._TextureSecond = Texture;

		this._Width = _Texture.Width;

		this._Position = 0;
	}

	public void Update()
	{
		_Position -= 0.5f;

		if (_Position < -_Width)
		{
			_Position += _Width;
		}
	}

	public void Draw()
	{
		_SpriteBatch.Draw(_Texture, new Vector2(_Position, 0), Color.White);
		_SpriteBatch.Draw(_TextureSecond, new Vector2(_Position + _Width, 0), Color.White);
	}
}

Uzay sınıfının Update() method'unda, arkaplan görselini sürekli 0.5 birim sola kaydırıyoruz.

Not : Arkaplan görseli kaydıkça ekrandan dışarı çıkıyor olacak, arkaplansız kalmamak için aslında ekrana yanyana iki tane arkaplan görseli çizdiriyoruz.

Gelelim bu sınıflardan değişkenlerimizi oluşturmaya ve oyun sınıfımıza eklemeye;

private Uzay Arkaplan;
private Ucak SavasUcagi;

protected override void LoadContent()
{
	spriteBatch = new SpriteBatch(GraphicsDevice);

	Arkaplan = new Uzay(Content.Load<Texture2D>("Uzay"), spriteBatch);
	SavasUcagi = new Ucak(Content.Load<Texture2D>("Ucak"));
	SavasUcagi.Position = new Vector2(50, PENCERE_YUKSEKLIK / 2);
}

Oyunumuzun Update() method’unda, klavye tuş vuruş durumlarına göre uçağımızı kontrol ediyor olacağız. Ayrıca Arkaplan değişkeninde bulunan Uzay sınıfının instance‘ından Update() method’unu çağırıyor olacağız. Böylece arkaplan görseli 0.5 birim sola kaymış olacak ve oyun penceresine yeni yerinde çizilecek.

protected override void Update(GameTime gameTime)
{
	KeyboardState ks = Keyboard.GetState();

	if (ks.IsKeyDown(Keys.Escape))
		this.Exit();

	if (ks.IsKeyDown(Keys.Left))
		SavasUcagi.Position.X -= (ks.IsKeyDown(Keys.LeftShift) || ks.IsKeyDown(Keys.RightShift)) ? 6 : 3;

	if (ks.IsKeyDown(Keys.Right))
		SavasUcagi.Position.X += (ks.IsKeyDown(Keys.LeftShift) || ks.IsKeyDown(Keys.RightShift)) ? 6 : 3;

	if (ks.IsKeyDown(Keys.Up))
		SavasUcagi.Position.Y -= 3;

	if (ks.IsKeyDown(Keys.Down))
		SavasUcagi.Position.Y += 3;

	if (SavasUcagi.Position.X < 0)
		SavasUcagi.Position.X = 0;

	if (SavasUcagi.Position.X > PENCERE_GENISLIK - SavasUcagi.Size.X)
		SavasUcagi.Position.X = PENCERE_GENISLIK - SavasUcagi.Size.X;

	if (SavasUcagi.Position.Y < 0)
		SavasUcagi.Position.Y = 0;

	if (SavasUcagi.Position.Y > PENCERE_YUKSEKLIK - SavasUcagi.Size.Y)
		SavasUcagi.Position.Y = PENCERE_YUKSEKLIK - SavasUcagi.Size.Y;

	Arkaplan.Update();

	base.Update(gameTime);
}

Uçağı sağa/sola yönetmek için kullandığımız ok tuşlarına (LeftRight) basılırken, Shift tuşlarından birine (LeftShiftRightShift) basılıyorsa, uçağı normalin iki katı hızlı ilerletiyoruz (3 birim yerine 6 birim)

Son olarak, Draw() method’unda uçağı ekrana çizdirecek ve Uzay sınıfının instance‘ının (Arkaplan değişkeni) Draw() method’unu çağıracağız;

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

	spriteBatch.Begin();

	Arkaplan.Draw();
	spriteBatch.Draw(SavasUcagi.Texture, SavasUcagi.Position, Color.White);

	spriteBatch.End();

	base.Draw(gameTime);
}

Sonuç olarak, yukarıdaki kodları yazdıktan sonra oyun projemizi başlatırsak;

XNA ile Oyun Programlama - Hareketli Arka Plan Ekran Görüntüsü

Hareketli ArkaPlan oyun projemizin kodlarını buradan indirebilirsiniz.

XNA ile ekranda UzayGemisi yönetmek

06 Mart 2010 3 yorum

Bu yazımı okumadan önce XNA konusundaki diğer makalelerimi okumanızı öneririm.

Öncelikle ihtiyacınız olacak iki görseli buradan indirebilirsiniz;

XNA - Oyun Programlama - Uzay Arkaplanı XNA - Oyun Programlama - Uzay Gemisi

Yapmak istediğimiz;

  • 800 x 600 pencere içerisinde arkaplanda Uzay.jpg görselini göstermek
  • Pencerenin ortasına UzayGemisi.png dosyasını konumlandırmak
  • Klavyenin tuşlarına görevler atayarak, UzayGemisi‘ni Uzay içerisinde yönetmek

Hemen başlayalım, ilk olarak yeni bir XNA projesi oluşturalım. Game1.cs dosyasının adını GameLoop.cs olarak değiştirelim.

Uzay.jpg ve UzayGemisi.png dosyalarını Content içerisine sürükleyip bırakalım. GameLoop.cs dosyasını açarak kod yazmaya başlayalım;

Sabitlerimizi class seviyesinde const ve readonly field’larda tanımlayalım;

private const int PENCERE_GENISLIK = 800;
private const int PENCERE_YUKSEKLIK = 600;
private const string PENCERE_BASLIK = "XNA - Uzay'da UzayGemisi Yönetelim";
private const bool TAM_EKRAN = false;
private readonly Color ARKAPLAN_RENK = Color.Black;

GameLoop class‘ının constructor‘ında bu sabitleri kullanalım;

graphics.PreferredBackBufferWidth = PENCERE_GENISLIK;
graphics.PreferredBackBufferHeight = PENCERE_YUKSEKLIK;
graphics.IsFullScreen = TAM_EKRAN;
this.Window.Title = PENCERE_BASLIK;

Uzay görselimizi 800 x 600 boyutlarındaki oyun penceremize sığdırmak için class seviyesinde Rectangle tipinde bir değişken tanımlayalım, Uzay ve UzayGemisi görsellerimiz için de birer tane Texture2D tipinde değişken tanımlayalım;

Rectangle Pencere;
Texture2D Uzay;
Texture2D UzayGemisi;

LoadContent() method’unda bu değişkenlerin değerlerini atayalım;

Pencere = new Rectangle(0, 0, PENCERE_GENISLIK, PENCERE_YUKSEKLIK);
Uzay = Content.Load<Texture2D>("Uzay");
UzayGemisi = Content.Load<Texture2D>("UzayGemisi");

Artık Uzayımızı ve UzayGemimizi oyun penceresine çizebiliriz. Ama madem uzay gemisini klavye tuşları ile yönetmek istiyoruz, o zaman uzay gemisinin kendi çevresinde dönebilmesini de sağlamamız gerekir.

Eğer bunu yapmazsak, Yukarı tuşu ile yukarı giden uzay gemisi, Aşağı tuşu ile aşağı gelirken yönünü düzeltmez, geri geri geliyormuş gibi gözükür. Hatta yanlara ve çağrazlara giderken iyice anlamsız görünmeye başlar.

Öncelikle uzay gemisinin o anda oyun penceresinin neresinde olduğunu tutacağımız Vector2 sınıfında bir değişkene class seviyesinde ihtiyacımız var, ayrıca uzay gemisinin gideceği yöne göre yönelmesi için, iki değişkene daha ihtiyacımız olacak;

Vector2 Konum = Vector2.Zero;
Vector2 Merkez;
float Yonelme = 0;

Uzay gemisinin doğru bir yönelme yapabilmesi için, ağırlık merkezini doğru vermemiz gerekiyor, LoadContent() methoduna aşağıdaki kodu ekleyelim;

Merkez = new Vector2(UzayGemisi.Width / 2, UzayGemisi.Height / 2);

Önce Draw() methodumuzu yazalım;

GraphicsDevice.Clear(ARKAPLAN_RENK);
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

spriteBatch.Draw(Uzay, Pencere, Color.White);
spriteBatch.Draw(UzayGemisi, Konum, null, Color.White, Yonelme, Merkez, 1, SpriteEffects.None, 0);

spriteBatch.End();
base.Draw(gameTime);

Son olarak Update() methodumuzu yazalım;

Öncelikle klavyenin o andaki durumunu tutacağımız değişkenimizi tanımlıyoruz;

KeyboardState ks = Keyboard.GetState();

Eğer Escape tuşuna basılıyorsa, oyunda çıkıyoruz;

if (ks.IsKeyDown(Keys.Escape))
	this.Exit();

Eğer hem Yukarı, hem de Sağa tuşlarına basılıyorsa, uzay gemisinin X ve Y koordinatlarında güncellemeler yapıp, yönelmesini 45 derecenin radian karşılığına eşitliyoruz;

if (ks.IsKeyDown(Keys.Up) && ks.IsKeyDown(Keys.Right))
{
	Konum.Y -= 3;
	Konum.X += 3;
	Yonelme = MathHelper.ToRadians(45);
}

MathHelper.ToRadians() parametre olarak derece cinsinden değer alır ve geriye float cinsinden radian döner.

Update() methodunun geri kalanında yön tuşlarına göre uzay gemisinin koordinatlarını ve yönelmesini güncelliyoruz;

if (ks.IsKeyDown(Keys.Up) && ks.IsKeyDown(Keys.Right))
{
	Konum.Y -= 3;
	Konum.X += 3;
	Yonelme = MathHelper.ToRadians(45);
}
else if (ks.IsKeyDown(Keys.Up) && ks.IsKeyDown(Keys.Left))
{
	Konum.Y -= 3;
	Konum.X -= 3;
	Yonelme = MathHelper.ToRadians(315);
}
else if (ks.IsKeyDown(Keys.Down) && ks.IsKeyDown(Keys.Right))
{
	Konum.Y += 3;
	Konum.X += 3;
	Yonelme = MathHelper.ToRadians(135);
}
else if (ks.IsKeyDown(Keys.Down) && ks.IsKeyDown(Keys.Left))
{
	Konum.Y += 3;
	Konum.X -= 3;
	Yonelme = MathHelper.ToRadians(225);
}
else if (ks.IsKeyDown(Keys.Up))
{
	Konum.Y -= 3;
	Yonelme = MathHelper.ToRadians(0);
}
else if (ks.IsKeyDown(Keys.Down))
{
	Konum.Y += 3;
	Yonelme = MathHelper.ToRadians(180);
}
else if (ks.IsKeyDown(Keys.Left))
{
	Konum.X -= 3;
	Yonelme = MathHelper.ToRadians(270);
}
else if (ks.IsKeyDown(Keys.Right))
{
	Konum.X += 3;
	Yonelme = MathHelper.ToRadians(90);
}

Son olarak Update() methodunda uzay gemisinin pencereden dışarı çıkmasını engelleyecek kontrol kodlarını da yazıyoruz;

if (Konum.X < 0)
	Konum.X = 0;
if (Konum.X > PENCERE_GENISLIK - UzayGemisi.Width)
	Konum.X = PENCERE_GENISLIK - UzayGemisi.Width;
if (Konum.Y < 0)
	Konum.Y = 0;
if (Konum.Y > PENCERE_YUKSEKLIK - UzayGemisi.Height)
	Konum.Y = PENCERE_YUKSEKLIK - UzayGemisi.Height;

“Oyun” projemizin kodlarını buradan bilgisayarınıza indirebilirsiniz.

Projeyi çalıştırdığınızda aşağıdaki gibi bir sonuç almanız lazım;

XNA - Uzay Oyunu Sonuç Penceresi

ASP.NET ile Mobil Kullanıcıları Mobil Sayfaya Yönlendirmek

27 Şubat 2010 3 yorum

ASP.NET 4.0 ile aşağıdaki kod yardımıyla mobil kullanıcıları algılayabilir ve uygulamanın mobil sayfasına yönlendirebilirsiniz;

private static readonly Regex MobileRegex = new Regex(@"(nokia|sonyericsson|blackberry|IPHONE|samsung|sec-|windows ce|motorola|mot-|up.b|midp-)", RegexOptions.IgnoreCase | RegexOptions.Compiled);

public bool IsMobile
{
	get
	{
		HttpRequest r = HttpContext.Current.Request;

		if (r.Browser.IsMobileDevice)
			return true;

		if (!string.IsNullOrEmpty(r.UserAgent) && MobileRegex.IsMatch(r.UserAgent))
			return true;

		return false;
	}
}

protected void Page_Load(object sender, EventArgs e)
{
	if (IsMobile)
		Response.RedirectPermanent("Mobile.aspx", true);
}

C# const ve readonly farkı

22 Şubat 2010 Yorum yapılmamış

Senaryo : Uygulama çalışırken değeri değiştirilemeyecek değişken tanımlamanız gerekiyor.

Çözüm : Muhtemel iki çözüm var, const ve readonly değişken tanımlamak. Fakat aralarında önemli bir fark var;

const : Türkçe’ye Sabit olarak çevrilebilir. Class seviyesinde tanımlanır ve tanımlanma anında değeri verilmek zorundadır. Sonradan değeri değiştirilemez.

readonly : Sadece-Okunabilir anlamına gelir. Class seviyesinde tanımlanır. Tanımlandığı anda değeri verilebilir veya Class Constructor’ında değeri verilebilir. Sonradan değeri değiştirilemez.

public class Matematik
{
	private const double PI = 3.14159;
}
public class Matematik
{
	private readonly int PI; /// PI değişkeninin değerini burada da verebilirdim.

	public Matematik()
	{
		PI = 22 / 7;
	}
}

C# Auto-Implemented Properties Özelliği

20 Ocak 2010 Yorum yapılmamış

Uygulamalarımızı geliştirirken birçok class veya struct yazmamız gerekir.

Bu class veya struct‘ların hemen hepsinde özelliklere (properties) ihtiyaç duyarız.

Çünkü, local değişkenlerin public değil, private olmasını isteriz. Bu durumda yapmamız gereken public olmasını istediğimiz local değişkenlere birer tane özellik (property) yazmaktır.

Örnek Personel Class‘ı aşağıdaki gibi olacaktır;

public class Personel
{
	private int PersonelId;
	private string AdSoyad;
}
public class Personel
{
	private int _PersonelId;
	private string _AdSoyad;

	public int PersonelId
	{
		get { return _PersonelId; }
		set { _PersonelId = value; }
	}

	public string AdSoyad
	{
		get { return _AdSoyad; }
		set { _AdSoyad = value; }
	}
}

Sadece okuma/yazma yapan iki özellik için ne faz kod yazdık, değil mi?

Eğer get/set blokları arasına özel iş yapan kod yazmamız gerekiyorsa, yukarıdaki gibi yapmaya devam etmeliyiz.

Fakat sadece okuma/yazma yapan özellikleri C# 3.0‘dan itibaren daha kısa yazabiliyoruz;

public class Personel
{
	public int PersonelId { get; set; }

	public string AdSoyad { get; set; }
}

Gördüğünüz gibi local değişkenlerin oluşturulması ve yönetilmesi işini yapmakla uğraşmıyoruz.

Eğer local değişkenlerin nasıl oluşturulduğunu merak ediyorsanız, projenizi compile ettikten sonra, ortaya çıkan exe/dll dosyasını ILDASM (Intermediate Language Disassembler) tool’u ile açıp bakabilirsiniz.

PersonelId özelliği için <>k__AutomaticallyGeneratedPropertyField0 isimli bir değişkenin oluşturulduğu ve tipininde int olduğunu göreceksiniz.

Otomatik oluşturulan değişken’in ismini herhangi bir kod parçasında kullanmaya çalışırsak, derleme (compile) zamanında yazım hatası (syntax error) alırız, yani local değişkenleri kullanamayız.

Eski stil kodlamada sadece okunabilir (readonly) veya sadece yazılabilir (writeonly) property tanımlayabiliyorduk. Bunu yeni stil kodlamada da yapabilir miyiz?

Cevap Evet, aşağıdaki kodu inceleyin;

public class Personel
{
	public int PersonelId { get; private set; }
	public string AdSoyad { private get; set; }
}