Switch | Engin Polat\'ın Windows 8 , Windows Phone 8 ve C# içerikli programcılık sitesi

Arşiv

Etiketlenen yazılar switch

AçıkAkademi C# uygulaması geliştirmek istiyorum Eğitimleri 2016

26 August 2016 Yorum yapılmamış

AçıkAkademi üzerinde yayınlanan 16 video’luk C# uygulama geliştirme eğitim seti yayına alındı.
Sevgili arkadaşım Bora Kaşmer ile hazırladığımız eğitim setini sizler de C# uygulaması geliştirmek istiyorum başlıklı AçıkAkademi sayfasından izleyebilirsiniz. Eğitim konu listesi;

  • Açılış
  • C# Hakkında
  • Visual Studio
  • İlk Proje
  • Rakamsal Veri Tipleri-1
  • Rakamsal Veri Tipleri-2
  • Tarihsel Veri Tutabilen Değişkenler-1
  • Tarihsel Veri Tutabilen Değişkenler-2
  • Liste Tipinde Değişkenler
  • For Döngüsü
  • ForEach Döngüsü
  • Switch
  • Sınıflar ve Öğeler
  • Özellikler ve Enumlar
  • Metodlar
  • C# Eğitiminden En İyi Nasıl Faydalanabilirim?

AçıkAkademi için bu eğitim setini çekmemizi sağlayan sevgili arkadaşım Ümit Batu‘ya da teşekkür ederim.

Windows Phone 8 – XNA Oyunu / Savaşa Hayır

12 January 2014 1 yorum

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

Önce görseller;

Savaşa Hayır : BackgroundSavaşa Hayır : Drop 1 0Savaşa Hayır : Drop 1 1Savaşa Hayır : Drop 2 0Savaşa Hayır : Drop 2 1Savaşa Hayır : Plane 0Savaşa Hayır : Plane 1Savaşa Hayır : Plane 2Savaşa Hayır : Plane 3Savaşa Hayır : Plane 4Savaşa Hayır : Plane 5

İlk olarak XNA Game Studio 4.0 grubundaki Windows Phone Game şablonundan SavasaHayir isimli projeyi oluşturalım;

Windows Phone : XNA Game Project Template

Game1.cs dosyasının ismini GameLoop.cs olarak değiştirdikten sonra, Plane isminde yeni bir class ekleyelim;

public class Plane
{
	public Texture2D Texture;

	public int Location;

	public int Speed;
}

Plane sınıfı sayesinde, ekrana getireceğimiz uçakların telefon ekranındaki konumlarını, hızlarını ve görsellerini bileceğiz.

Drop isminde yeni bir class daha ekleyelim ve aşağıdaki kod parçası ile güncelleyelim;

public class Drop
{
	public bool IsBox;

	public bool IsParachute;

	public Vector2 Location;
}

GameLoop sınıfına geri dönelim ve sınıf seviyesindeki değişkenlere aşağıdakileri ekleyelim;

GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;

Random r = new Random();

Texture2D BackgroundTexture;

Texture2D BoxTexture;
Texture2D BoxParachuteTexture;

Texture2D HumanTexture;
Texture2D HumanParachuteTexture;

Texture2D[] PlaneTextures = new Texture2D[6];

List<Plane> PlaneList = new List<Plane>();

List<Drop> DropList = new List<Drop>();

TimeSpan LastPlaneDate = TimeSpan.Zero;

int PlaneCount;
int DropCount;
int HelpCount;

Yukarıdaki kodlar için daha önce yazmış olduğum Windows Phone ve XNA konusundaki diğer makalelerimi okumanızı öneririm.

GameLoop sınıfının constructor‘ında aşağıdaki atama işlerini yapalım;

public GameLoop()
{
	graphics = new GraphicsDeviceManager(this);
	Content.RootDirectory = "Content";

	TargetElapsedTime = TimeSpan.FromTicks(333333);

	InactiveSleepTime = TimeSpan.FromSeconds(1);

	graphics.PreferredBackBufferWidth = 480;
	graphics.PreferredBackBufferHeight = 800;

	graphics.IsFullScreen = true;
}

LoadContent method’unda Texture2D tipindeki değişkenlerimize değer atayalım;

spriteBatch = new SpriteBatch(GraphicsDevice);

BackgroundTexture = Content.Load<Texture2D>("Background");

for (int iLoop = 0; iLoop < 6; iLoop++)
{
	PlaneTextures[iLoop] = Content.Load<Texture2D>("Plane" + iLoop);
}

BoxTexture = Content.Load<Texture2D>("Drop1_0");
BoxParachuteTexture = Content.Load<Texture2D>("Drop1_1");

HumanTexture = Content.Load<Texture2D>("Drop2_0");
HumanParachuteTexture = Content.Load<Texture2D>("Drop2_1");

Update method'unda Plane ve Drop listesindeki elemanların yerlerini güncelliyoruz;

foreach (var plane in PlaneList)
{
	plane.Location += plane.Speed;
}

foreach (var drop in DropList)
{
	drop.Location.Y += 4;
}

Son uçak üretme zamanımızdan itibaren 5000ms (5sn) geçtiyse yeni uçak üretme kodunu ekliyoruz;

LastPlaneDate += gameTime.ElapsedGameTime;

if (LastPlaneDate > TimeSpan.FromMilliseconds(5000))
{
	var plane = new Plane();

	plane.Texture = PlaneTextures[r.Next(0, 6)];

	plane.Speed = r.Next(3, 8);

	PlaneList.Add(plane);

	PlaneCount++;

	LastPlaneDate = TimeSpan.Zero;
}

Windows Phone oyunlarında, oyuncunun ekrana dokunduğu noktaların listesini TouchPanel sınıfının static GetState methodundan dönen TouchCollection ile alabilmekteyiz.

TouchCollection koleksiyonunun her bir elemanı TouchLocation tipindedir, State özelliğinin TouchLocationState enum’ından Pressed değerinde olduğunu kontrol ederek, ilgili noktaya dokunulduğu durumu yakalayabiliriz.

Eğer dokunulan nokta bir Plane ile kesişiyorsa, rastgele yeni bir Drop düşürebiliriz, Drop ile kesişiyorsa paraşütünün açılmasını sağlayabiliriz;

foreach (var tl in TouchPanel.GetState())
{
	if (tl.State == TouchLocationState.Pressed)
	{
		var touchArea = new Rectangle((int)tl.Position.X, (int)tl.Position.Y, 1, 1);

		foreach (var plane in PlaneList)
		{
			var planeArea = new Rectangle(plane.Location, 20, plane.Texture.Width, plane.Texture.Height);

			if (planeArea.Intersects(touchArea))
			{
				var drop = new Drop();

				drop.Location = new Vector2(tl.Position.X, 20);

				drop.IsBox = (r.Next(0, 2) == 0);

				DropList.Add(drop);

				DropCount++;

				return;
			}
		}

		foreach (var drop in DropList)
		{
			var dropArea = new Rectangle((int)drop.Location.X, (int)drop.Location.Y, 100, 200);

			if (!drop.IsParachute && dropArea.Intersects(touchArea))
			{
				drop.IsParachute = true;

				HelpCount++;

				return;
			}
		}
	}
}

Son olarak Draw method’unda elimizdeki arkaplan görselini, ekrandaki uçakları, paraşütü açılmış ve açılmamış nesneleri ekrana çizdireceğiz;

GraphicsDevice.Clear(Color.CornflowerBlue);

spriteBatch.Begin();

spriteBatch.Draw(BackgroundTexture, Vector2.Zero, Color.White);

foreach (var plane in PlaneList)
{
	spriteBatch.Draw(plane.Texture, new Vector2(plane.Location, 20), Color.White);
}

foreach (var drop in DropList)
{
	if (drop.IsBox && drop.IsParachute)
	{
		spriteBatch.Draw(BoxParachuteTexture, drop.Location, Color.White);
	}
	else if (drop.IsBox && !drop.IsParachute)
	{
		spriteBatch.Draw(BoxTexture, drop.Location, Color.White);
	}
	else if (!drop.IsBox && drop.IsParachute)
	{
		spriteBatch.Draw(HumanParachuteTexture, drop.Location, Color.White);
	}
	else
	{
		spriteBatch.Draw(HumanTexture, drop.Location, Color.White);
	}
}

spriteBatch.End();

Oyun’dan bir ekran görüntüsü;

Savaşa Hayır : Screenshot

Windows Phone 8 – XNA Oyunu / PlaneHunter

18 February 2013 3 yorum

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

Her zamanki gibi önce görseller;

PlaneHunter : BackgroundPlaneHunter : CoinPlaneHunter : Target1PlaneHunter : Target2PlaneHunter : Target3PlaneHunter : Target4PlaneHunter : Target5PlaneHunter : Target6PlaneHunter : Target7

Bir tane de Sprite Font dosyamız var, HitCountFont.spritefont ismini verdiğim dosyanın, “yorum satırları kaldırılmış halini” aşağıdaki gibi düzenledim;

<?xml version="1.0" encoding="utf-8"?>
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
	<Asset Type="Graphics:FontDescription">
		<FontName>Segoe UI Mono</FontName>
		<Size>14</Size>
		<Spacing>0</Spacing>
		<UseKerning>true</UseKerning>
		<Style>Regular</Style>
		<CharacterRegions>
			<CharacterRegion>
				<Start> </Start>
				<End>~</End>
			</CharacterRegion>
		</CharacterRegions>
	</Asset>
</XnaContent>

İlk olarak XNA Game Studio 4.0 grubundaki Windows Phone Game şablonundan PlaneHunter isimli projeyi oluşturalım;

Windows Phone : XNA Game Project Template

Game1.cs dosyasının ismini GameLoop.cs olarak değiştirdikten sonra, Target isminde yeni bir class ekleyelim;

public class Target
{
	public Texture2D Texture;

	public Vector2 Position;

	public Vector2 Velocity;

	public Rectangle Area;

	public SpriteEffects Effect;

	public bool IsAlive;

	public Target(Texture2D texture)
	{
		this.Texture = texture;

		this.IsAlive = true;

		this.Area = new Rectangle(0, 0, texture.Width, texture.Height);
	}
}

Target sınıfı sayesinde, ekrana getireceğimiz hedef‘lerin ekranın neresinden çıkıp, hangi yöne doğru gideceğini, hedefin vurulup/vurulmadığını, çarpışma testi yapabilmek için ekranda kapladığı alanı ve hızını bileceğiz.

GameLoop sınıfına geri dönelim ve sınıf seviyesindeki değişkenlere aşağıdakileri ekleyelim;

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

private Texture2D backgroundTexture;

private readonly Texture2D[] targetTextures = new Texture2D[7];

private Texture2D coinTexture;
private Rectangle coinPart;
private int coinPartIndex = 0;

private SpriteFont hitCountFont;
private int targetHitCount = 0;

private readonly List targetList = new List();

private TimeSpan lastTargetSpawnTime = TimeSpan.Zero;

private readonly Rectangle screenArea = new Rectangle(0, 0, PENCERE_GENISLIK, PENCERE_YUKSEKLIK);

private readonly Random r = new Random();

Yukarıdaki kodlar için daha önce yazmış olduğum Windows Phone ve XNA konusundaki diğer makalelerimi okumanızı öneririm.

GameLoop sınıfının constructor‘ında aşağıdaki atama işlerini yapalım;

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

graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight;

SupportedOrientations özelliğine DisplayOrientation enum’ından LandscapeLeft ve LandscapeRight değerlerini atayarak, oyun ekranının telefon dikey değil, yatay tutulduğunda düzgün görüntüleneceğini tanımlamış olduk.

LoadContent method’unda Texture2D tipindeki değişkenlerimize değer atayalım;

backgroundTexture = Content.Load<Texture2D>("PlaneHunterBackground");

coinTexture = Content.Load<Texture2D>("PlaneHunterCoin");
hitCountFont = Content.Load<SpriteFont>("PlaneHunterHitCountFont");

for (int i = 0; i < targetTextures.Length; i++)
{
	targetTextures[i] = Content.Load<Texture2D>("PlaneHunterTarget" + (i + 1));
}

Update method’unda son hedef üretilme zamanından itibaren yeterli süre geçmişse, yeni hedef oluşturmamız lazım;

lastTargetSpawnTime += gameTime.ElapsedGameTime;

if (lastTargetSpawnTime > TimeSpan.FromMilliseconds(1500))
{
	Target t = new Target(targetTextures[r.Next(0, 7)]);
	switch (r.Next(0, 4))
	{
		case 0:
		default:
			t.Position = new Vector2(r.Next(100, 300), 480);
			t.Velocity = new Vector2((float)r.NextDouble() * 8 + 2, (float)r.NextDouble() * -4 - 2);
			t.Effect = SpriteEffects.FlipHorizontally;
			break;
		case 1:
			t.Position = new Vector2(r.Next(500, 700), 480);
			t.Velocity = new Vector2((float)r.NextDouble() * -8 - 2, (float)r.NextDouble() * -4 - 2);
			t.Effect = SpriteEffects.None;
			break;
		case 2:
			t.Position = new Vector2(r.Next(100, 300), 0);
			t.Velocity = new Vector2((float)r.NextDouble() * 8 + 2, (float)r.NextDouble() * 4 + 2);
			t.Effect = SpriteEffects.FlipHorizontally;
			break;
		case 3:
			t.Position = new Vector2(r.Next(500, 700), 0);
			t.Velocity = new Vector2((float)r.NextDouble() * -8 - 2, (float)r.NextDouble() * 4 + 2);
			t.Effect = SpriteEffects.None;
			break;
	}

	targetList.Add(t);

	lastTargetSpawnTime = TimeSpan.Zero;
}

Yeni hedef ekleyeceğimiz zaman öncelikle hedef’i ekranın dört köşesinden rastgele birtanesine koyup, rastgele hız veriyoruz. Böylece hedefler ekranın rastgele bir yerinden çıkıp rastgele hızla rastgele bir yöne doğru hareket edecek.

Update method’unda o esnada ekranda olan hedeflerin yerlerini ve ekranda kapladıkları alanı güncelliyoruz;

foreach (Target hedef in targetList)
{
	hedef.Position += hedef.Velocity;

	hedef.Area.X = (int)hedef.Position.X;
	hedef.Area.Y = (int)hedef.Position.Y;
}

Windows Phone oyunlarında, oyuncunun ekrana dokunduğu noktaların listesini TouchPanel sınıfının static GetState methodundan dönen TouchCollection ile alabilmekteyiz.

TouchCollection koleksiyonunun her bir elemanı TouchLocation tipindedir, State özelliğinin TouchLocationState enum’ından Pressed değerinde olduğunu kontrol ederek, ilgili noktaya dokunulduğu durumu yakalayabilir, eğer bir hedef ile kesişiyorsa, hedefi öldürebiliriz;

TouchCollection tc = TouchPanel.GetState();
foreach (TouchLocation tl in tc)
{
	if (tl.State == TouchLocationState.Pressed)
	{
		Rectangle touchArea = new Rectangle((int)tl.Position.X, (int)tl.Position.Y, 1, 1);

		foreach (Target hedef in targetList)
		{
			if (hedef.Area.Intersects(touchArea))
			{
				hedef.Velocity = Vector2.Zero;

				hedef.IsAlive = false;

				targetHitCount++;
			}
		}
	}
}

Update method’unda, ekran sınırları dışına çıkan hedefleri listeden çıkartmalıyız. Eğer ekran dışına çıkan hedefleri listeden temizlemezsek, liste zamanla çok büyüyecek, telefonun kısıtlı olan hafızasını dolduracak ve oyunun önce yavaşlamasına sonra kapanmasına yol açabilecektir.

foreach (Target hedef in targetList)
{
	if (!hedef.Area.Intersects(screenArea))
	{
		targetList.Remove(hedef);

		break;
	}
}

Draw method’unda elimizdeki arkaplan görselini, hayatta olan hedefleri, hayatta olmayan hedefler için kendi etrafında dönen altın görselini ve toplam kaç hedefin vurulduğunu gösteren skor‘u ekrana çizdireceğiz;

spriteBatch.Begin();

spriteBatch.Draw(backgroundTexture, Vector2.Zero, Color.White);

foreach (Target hedef in targetList)
{
	if (hedef.IsAlive)
	{
		spriteBatch.Draw(hedef.Texture, hedef.Position, null, Color.White, 0, Vector2.Zero, 1, hedef.Effect, 0);
	}
	else
	{
		spriteBatch.Draw(coinTexture, hedef.Position, coinPart, Color.White);
	}
}

spriteBatch.DrawString(hitCountFont, "Hit Count : " + targetHitCount, new Vector2(10, 10), Color.Black);
spriteBatch.DrawString(hitCountFont, "Hit Count : " + targetHitCount, new Vector2(9, 9), Color.White);

spriteBatch.End();

Oyunumuzdan bir kare;

Windows Phone - XNA Oyunu : PlaneHunter

Oyunun kodlarını buradan indirebilirsiniz.

C# switch ifadelerinde explicit fall through

11 January 2010 1 yorum

Explicit Fall Through : Uygulamanın ilgili değişkenin değerine göre, switch ifadesindeki case‘lerden uygun olana dallanması ve break görene kadar, koddan aşağı doğru, diğer case‘lere girerek ilerlemesidir.

C# dilinde switch ifadelerinde explicit fall through desteklenmez.

Bu yüzden aşağıdaki kod, derleme zamanında hata verecektir ve derlenmeyecektir.

switch(değişken)
{
	case 0:
		/// 0 durumda çalışacak kod
	case 1:
		/// hem 0, hem de 1 durumunda çalışacak kod
	case 2:
		/// hem 0, hem 1, hem de 2 durumunda çalışacak kod
		break;
}

Yukarıdaki kod parçasını C#’ta çalıştırmak istiyorsak, aşağıdaki gibi yazabiliriz;

switch(değişken)
{
	case 0:
		/// 0 durumda çalışacak kod
		goto case 1;
	case 1:
		/// hem 0, hem de 1 durumunda çalışacak kod
		goto case 2;
	case 2:
		/// hem 0, hem 1, hem de 2 durumunda çalışacak kod
		break;
}

Bu sayede, case’ler arasındaki akış açıkça belirtilmiş olur.