1 Şub 2016

C#'da Köstebek Yakalama Oyunu Nasıl Yapılır?


Oyunda dinamik olarak butonlar tanımlanarak, köstebeğin çıkabileceği butonlar oluşturuluyor. Ve puan 10, 15, 20, 30 ve 40 olduğunda seviye sürekli arttırılıyor. Seviye arttırmadan kasıt köstebeğin hızı artıyor ve köstebeği yakalama alanımız gittikçe büyüyor. Kırmızı butonlar köstebeği temsil ederken bunlara basınca puanımız artmaktadır. Gri butonlar ise puanımızı azaltmaktadır. Oyunun kodları ve ekran görüntüleri aşağıdaki gibidir.

Bu form tasarımız, butonlar burada gözükmüyor çünkü butonlarımızı for döngüsü kullanarak dinamik olarak oluşturduk.

Bu ekran ise oyunumuz çalışmaya başladıktan sonraki ilk aşama ekranıdır. Kırmızı butonumuz bizim kösteeğimizdir ve ona tıklarsak yani onu yakalarsak puanımız artacaktır. Diğer butonlar ise tuzaklardır.

Köstebek oyunu kodları aşağıda bulunmaktadır. İsteyenler kaynak dosyayı, buradan direk olarak bilgisayarına da indirebilir.
/* 
        WindowsState Properties'ini Maximize yaparak açılacak olan form'un tam ekran olarak açılmasını sağlayabiliriz. Böylece width/genişlik boyu sabit olarak kalacaktır.
        */
        #region degiskenler
        int rndAdet;
        int formGenisligi;
        string butonAdi;
        int puan = 0;
        int sayi2;
        int saniye = 0;
        #endregion
        private void Form1_Load(object sender, EventArgs e)
        {
            formGenisligi = this.Width; //tam ekran olarak açılacak olan ekranın genişliği 1382 değeri formGenisligi degişkenine atanır.
            rndAdet = ButonOlustur(21); //Aşağıda ButonOlustur metodunu çok kullanacağımız için oluşturduk. Başlangıçta 21 değerini göndererek bu metodun bu parametreye göre bize bir değer döndürmesini sağladık. Ve bu değeri rndAdet değişkenimizde sakladık
            timer1.Start();
            timer2.Start();
        }
        int ButonOlustur(int adet)
        {
            int x; //Left değerimiz burada tutulacak
            int y = 40; //Top değerimiz burada tutulacak
            int sayac = 0; //Atnı satırda gönderilen adet'in karekökü kadar buton olsun ki g-form dışına taşma olmasın diye bunu kullanıcaz
            int deger = Convert.ToInt32(Math.Sqrt(adet)); //Gelen adet parametresinin karekökünü alıyoruz ve int'a çevirererk deger değişkenimize atıyoruz. 21 olan adet'in karekökü alınarak deger'a atanınca deger'in değeri 5 oluyor
            int butonsGenisligi = deger * 35; //bir butonun boyutunu (35), gelen parametrenin karekökü ile çarpıyoruz ve aynı doğrultuda kaç buton koyabiliriz bunu kontrol ediyoruz
            if (butonsGenisligi < formGenisligi) //tüm bu yanyana butonların genisliği formGenisliğine sığıyor mu kontrol edilir
            {
                x = (formGenisligi - butonsGenisligi) / 2; //Form'Un tam ortasından başlanılması için Left değerimize böyle bir atama yaptık.
                //Şimdi bu Left ve Top değerlerimizi kullanarak dinamik olarak buton Olusturalım
                for (int i = 1; i <= deger * deger; i++)
                {
                    sayac++;
                    Button btn = new Button(); //Button class'ından nesne türettik ve bu nesneni Property'lerini tanımlıyıcaz
                    btn.Name = i.ToString(); //Butonların ismi
                    btn.Height = 35; //Butonların yüksekliği
                    btn.Width = 35; //Butonların genişliği
                    btn.Click += Btn_Click; //btn.Click yazıp 2 kere tab'a basarsak otomatik olarak bizim için Click metodu tanımlanır
                    btn.Left = x; //Form'daki başlangıç Left değerimizi belirttik
                    btn.Top = y;  //Form'daki başlangıç Top değerimizi belirttik
                    if (sayac == deger)  //Eğer bir sırada deger kadar buton adeti olduysa y değeri arttırılarak yeni bir sıraya geçilir. Böylece hem Form'un genişliği aşılmaz hem de butonlar üst üste binmez
                    {
                        sayac = 0; //Sayaçı sıfırladık ki yeni satırda yeniden aynı kontrol sağlanabilsin
                        x = (formGenisligi - butonsGenisligi) / 2; //Başlangıç left'ini aynı değere aldık ki üstteki satır ile aynı hiza alınabilsin
                        y = y + 40; //Yeni satırdaki butonlar ile eski satırdaki butonların üst üste binmemesi için Top değerimizi arttırdık
                    }
                    else
                    {
                        x = x + 40; //Sayac, degere eşit değilse, eklenen butonların aralarında mesafe olmasını sağlamak için x, sayac değeri 5 olana kadar her defasında 40 arttırılır
                    }
                    //Şimdi butonlarımızı oluşturduk, bunlara isim verdik, boyutlarını belirttik, bu butonlara tıklandığında neler olacağını tanımlamak için Click event'İmizi de çalıştırdık. Ayrıca butonların üst üste binmemesi ve uygun şekilde sıralanması için koordinatlarımızı da belirttik. Sıra geldi butonumuzu Form'umuza eklemeye bunu da aşağıdaki gibi yapacağız.
                    this.Controls.Add(btn);
                }
            }
            else //Eğer butonların genişliği aynı sıraya sığmayack kadar büyük bir değer ise
            {
                MessageBox.Show("Butonların toplam genişliği aynı sıraya sığmayacak kadar geniş!");
            }
            return deger * deger; //rndAdet değişkenine atanacak olan değer
        }
        private void Btn_Click(object sender, EventArgs e)
        {
            Button btn = (Button)sender; //Gelen değerin buton olduğunu belirttim
            if (btn.BackColor == Color.Red)
            {
                if (butonAdi == btn.Name)
                {
                    return; //Aynı butona bir kere tıklamada bir kere puan arttırması için böyle bir kontrol kullanıyoruz
                }
                puan += 5; //BackColor'ı Kırmızı olan butona tıklarsa puanımız 5 puan artacaktır.
            }
            else
            {
                puan -= 5; //BackColor'ı Default Gri olan butona tıklarsa puanımız 5 puan azalacaktır.
            }
            butonAdi = btn.Name; //Tıkladığımız butonun adını butonAdi değişkeninde tutuyoruz ki buna bir daha tıklayıp tıklamadığımızı yukarıdakş gibi kontrol edebilelim
            lblPuan.Text = puan.ToString(); //puan değişkenimizi label'da gösteriyoruz.
            if (puan == 10)  //1o puana ulaşıldığında level atlanıyor 
            {
                ButonSil(); //ButonSil() metodu çalıştırılarak önce Form ekranı temizleniyor.
                rndAdet = ButonOlustur(41); //ButonOlustur metoduna parametre olarak 41 gonderiliyor
                timer1.Interval = 1000;     //Başlangıçta 2000 olan timer1'in Interval'i 1000'e düşürülüyor.
            }            
            else if (puan == 15) //puan 15 ise Level arttırılıyor
            {
                ButonSil(); //Yine Form ekranı temizleniyor
                rndAdet = ButonOlustur(61); //Parametre arttırılarak daha fazla buton oluşturuluyor
                timer1.Interval = 800; //Köstebeği yakalama süresi azaltılıyor
            }
            else if (puan == 20) //puan 15 ise Level arttırılıyor
            {
                ButonSil(); //Yine Form ekranı temizleniyor
                rndAdet = ButonOlustur(71); //Parametre arttırılarak daha fazla buton oluşturuluyor
                timer1.Interval = 750; //Köstebeği yakalama süresi azaltılıyor
            }
            else if (puan == 30) //puan 15 ise Level arttırılıyor
            {
                ButonSil(); //Yine Form ekranı temizleniyor
                rndAdet = ButonOlustur(85); //Parametre arttırılarak daha fazla buton oluşturuluyor
                timer1.Interval = 700; //Köstebeği yakalama süresi azaltılıyor
            }
            else if (puan == 40) //puan 15 ise Level arttırılıyor
            {
                ButonSil(); //Yine Form ekranı temizleniyor
                Random rnd = new Random();
                int deneme = rnd.Next(100, 400);    //Random olarak 100-400 arası bir sayı üretiliyor
                rndAdet = ButonOlustur(deneme); //Parametre olarak artık bu random sayı kullanılarak oyun iyice zorlaştırılıyor.
                timer1.Interval = 500; //Köstebeği yakalama süresi azaltılıyor
            }
        }
        void ButonSil()
        {
            for (int i = this.Controls.Count - 1; i >= 0; i--) //Döngü form'da ki kontrol sayısından geriye doğru döndürüldü
            {
                if (this.Controls[i].GetType() == typeof(Button)) //Her kontrolün tipine bakılarak, tipin buton olup olmadığı anlaşıldı
                {
                    this.Controls.RemoveAt(i); //Eğer yakalanan kontröl butonsa bu Form'dan silindi.
                }
            }
        }
        private void timer1_Tick(object sender, EventArgs e) //Butonlara BackColor atamak için bu timer kullanıldı
        {
            Random rnd = new Random();
            int sayi = rnd.Next(1, rndAdet); //1 ile rndAdet değişkenimizdeki değer arasında bir random sayı ürettik
            if (sayi == sayi2) //Bu kontrolü yapma amacımız köstebeğin aynı butonda üstüste bulunamamasını sağlamak, 1 buton ardarda 2 kere kırmızı yanamaz
            {
                ButonaRenkVer(0);
                return;
            }
            else
            {
                ButonaRenkVer(sayi);
                sayi2 = sayi;
            }
        }
        void ButonaRenkVer(int adet)
        {
            foreach (var item in this.Controls) //Form üzerindeki tüm kontrollere tek tek erişilir
            {
                if(item is Button) //Eğer erişilen bu kontrol Buton ise
                {
                    Button btn = (Button)item; //Gelen değerin buton olduğunu belirtiyoruz
                    btn.BackColor = Color.Gray; //Tüm butonların BackColor'u Gri yapılır
                    if(adet>0 && adet.ToString() == btn.Name) //Gelen parametre 0'dan büyükse ve butonun adı ile parametre aynı isimdeyse
                    {
                        btn.BackColor = Color.Red;
                    }
                }
            }
        }
        private void timer2_Tick(object sender, EventArgs e) //Bu timer'da da Süre kontrol edilir ve ekrana yazılır
        {
            saniye++; //Timer'ın intervali 1000 yapılır ve timer her Tick'ledğinide saniye 1 arttırılır
            lblZaman.Text = saniye.ToString(); //Arttırılıan bu saniye değişkeni ekranda gösterilir.
            if(saniye == 40)    //Süre 40'a eşitse oyun biter
            {
                timer1.Stop();
                timer2.Stop();
                MessageBox.Show("Süre bitti Puanınız {0}", lblPuan.Text);
            }
        }
    }

Hiç yorum yok:

Yorum Gönder