C# ile Oyun Yapımı

Merhaba arkadaşlar bugün sizlerle iki adet oyun yapacağız. Yılan oyunu ve Sayı dizme oyunu.

İlk olarak form giriş ekranını tasarlayalım


Form ekranına iki adet büyük buton ekledik. Şimdi sırada oyunların tasarımları var.

Sayı Dizme Oyunu

Sayı dizme oyunu ile başlayalım
Öncelikle bir adet picture box ve iki adet buton ekliyoruz. Süre için de bir adet timer ekliyoruz.


Oyun mantığı karışık olan sayıları 1-15 sırası ile dizmeye çalışmak.
Gelelim uyguladığımız algoritmaya,Bir fotoğraf seçiyoruz ve o fotoğrafı 15 eşit fotoğrafa parçalıyoruz. Ben bu(burdan indirebilirsiniz) fotoğrafı kullandım. 15 eşit fotoğrafı form üzerine düzenli bir şekilde yerleştiriyoruz. Bunu kod üstünde nasıl yapacağımıza bakalım.

Kodu

Öncelikle değişkenlerimizi tanımlayalım

List resimParcalari = new List();
        List resimAlanlari = new List();
        Bitmap CurrentBitmapImage;

Fotoğrafı parçalama bölümüne geçelim. Burada dikkat edilmesi gereken nokta resmin boyutu. Benim seçtiğim resim 280-*280 boyutunda, 4 satır ve 4 sütün var, bu yüzden küçük resim parçaları 70*70 boyutunda olmalı. Şimdi büyük resmi 15 eşit parçaya ayıralım.

 for (int i = 0; i < resimAlanlari.Count; i++)
            {
                this.Controls.Remove(resimAlanlari[i]);
            }
            resimAlanlari.Clear();
            resimParcalari.Clear();
            pictureBox1.Size = new System.Drawing.Size(280, 280);
            pictureBox1.Image = CurrentBitmapImage.Clone(new Rectangle(new Point(0, 0), new Size(280, 280)), System.Drawing.Imaging.PixelFormat.DontCare);
            pictureBox1.Visible = false;

            for (int i = 0; i < 16; i++)
            {
                resimParcalari.Add(CurrentBitmapImage.Clone(new Rectangle(new Point(i / 4 * 70, i % 4 * 70), new Size(70, 70)), System.Drawing.Imaging.PixelFormat.DontCare));
            }

Elimizde bir adet resim parçaları listesi var. Şimdi bu resim parçalarını rastgele bir şekilde form ekranı üzerine yerleştirelim. Oyunun amacı rastgele parçaları dizmek olduğu için resim parçalarını rastgele bir şekilde yerleştiriyoruz. Aynı zamanda bir adet boşluk bırakıyoruz. Boşluk resimde ki 16. fotoğrafa denk gelmeli buna dikkat ediyoruz. Oyun bitimini kontrol amaçlı resimlere birer tag ekliyoruz.

            List resimDagilimi = new List();
            Random rastgele = new Random();

            for (int i = 0; i < 15; i++)
            {
                int resimNo = rastgele.Next(15);
                if (!resimDagilimi.Contains(resimNo))
                {
                    resimDagilimi.Add(resimNo);
                }
                else
                {
                    i--;
                }

            }

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    if (!(j == 3 && i == 3))
                    {
                        PictureBox resim = new PictureBox();
                        resim.Click += new EventHandler(p_Click);
                        resim.Location = new Point(70 * i + 50, 70 * j + 50);
                        resim.BorderStyle = BorderStyle.FixedSingle;
                        resim.Size = new System.Drawing.Size(70, 70);
                        resim.Tag = resimDagilimi[i * 4 + j].ToString();
                        resim.Image = resimParcalari[resimDagilimi[i * 4 + j]];
                        resimAlanlari.Add(resim);
                        this.Controls.Add(resim);
                    }
                    else
                    {
                        bosYer = new Point(70 * 3 + 50, 70 * 3 + 50);
                    }
                }
            }

Resim yerleştirme işlemi bu kadar. Şimdi sırada tıklanma olayları var. Amacımız tıkladığımız resmin boş olan kısma ilerlemesi. Boş kısım sağ sol üst veya alt tarafta olabilir.

  void p_Click(object sender, EventArgs e)
        {
            PictureBox resim = (PictureBox)sender;

            if ((resim.Location.X - 70 == bosYer.X) && (resim.Location.Y == bosYer.Y))
            {
                resim.Location = bosYer;
                bosYer.X += 70;
                this.Focus();
            }
            else if (resim.Location.X + 70 == bosYer.X && (resim.Location.Y == bosYer.Y))
            {
                resim.Location = bosYer;
                bosYer.X -= 70;
                this.Focus();
            }
            else if (resim.Location.Y - 70 == bosYer.Y && (resim.Location.X == bosYer.X))
            {
                resim.Location = bosYer;
                bosYer.Y += 70;
                this.Focus();
            }

            else if (resim.Location.Y + 70 == bosYer.Y && (resim.Location.X == bosYer.X))
            {
                resim.Location = bosYer;
                bosYer.Y -= 70;
                this.Focus();
            }

            bool durum = OyunDurumunuKontrolEt();

            if (durum)
            {
                timer.Enabled = false;

                MessageBox.Show("Tebrikler oyunu tamamladınız", "Bilgi", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

Oyunun bitip bitmediğini anlamamız için bir fonksiyon yazmamız gerekiyor. Resimlere tag eklemiştik onu kullanıyoruz.

  private bool OyunDurumunuKontrolEt()
        {
            bool durum = true;
            for (int i = 0; i < resimAlanlari.Count; i++)
            {
                int id = int.Parse(resimAlanlari[i].Tag.ToString());

                if (!(resimAlanlari[i].Location.X == (id / 4) * 70 + 50 && resimAlanlari[i].Location.Y == (id % 4) * 70 + 50))
                {
                    durum = false;
                    break;
                }
            }


            return durum;
        }

Ve bitti. Timer ve diğer fonksiyonuları anlatmıyorum. Kaynak kodlarını yazının sonunda bulabilirsiniz.

Yılan Oyunu

Formk ekranından başlayalım. Yılanı çizmek için panel kullanacağız. Bir panel iki buton bir combobox ve 2 adet label ekliyoruz.

Kod

İlk olarak değişkenleri tanımlayarak başlayalım.

 private const Keys yukari = Keys.Up;
        private const Keys saga = Keys.Right;
        private const Keys asagi = Keys.Down;
        private const Keys sola = Keys.Left;

        private int posX;
        private int posY;
        private const int xMax = 69;
        private const int xMin = 0;
        private const int yMax = 46;
        private const int yMin = 0;

        private bool lastKeyProcessed = true;
        private int multiplier = 11;
        private int puan = 0;
        private yonEnum yon;
        private Point bait;
        private List poizsyon = new List();

Daha sonra yön adında bir enum oluşturalım.

    public enum yonEnum
        {
            tanimsiz,
            Yukari,
            Saga,
            Asagi,
            Sola
        }

Şimdi yılanı çizmeye başlayalım

   private void yilanCiz()
        {
            gameArea.Refresh();
            yemCiz();
            foreach (Point item in poizsyon)
            {
                int xVal = item.X * multiplier;
                int yVal = item.Y * multiplier;

                noktaCiz(xVal, yVal);
            }
        }

Sırada hız ayarımız var

  private void hizAyarla()
        {
            switch (cmbHiz.SelectedIndex)
            {
                case 0:
                    gameTimer.Interval = 100;
                    break;
                case 1:
                    gameTimer.Interval = 75;
                    break;
                case 2:
                default:
                    gameTimer.Interval = 50;
                    break;
                case 3:
                    gameTimer.Interval = 40;
                    break;
                case 4:
                    gameTimer.Interval = 25;
                    break;
                case 5:
                    gameTimer.Interval = 10;
                    break;
            }
        }

Sıfırlama ve yeni oyun fonksiyonlarımızı tanımlıyoruz.

     private void sifirla()
        {
            posX = 12;
            posY = 20;
            puan = 0;
            yon = yonEnum.Saga;
            cizim();
        }

        private void yeniOyun()
        {
            poizsyon.Clear();
            poizsyon.Add(new Point(12, 20));
            poizsyon.Add(new Point(11, 20));
            poizsyon.Add(new Point(10, 20));
        }

Klavyeden alınan tuşları enum tuşlarına eşitliyoruz.

   protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (gameTimer.Enabled && lastKeyProcessed && keyData != Keys.P)
            {
                lastKeyProcessed = false;
                pozisyonBelirle(keyData);
            }

            bekle(keyData);
            return base.ProcessCmdKey(ref msg, keyData);
        }

Daha sonra yön belirliyoruz.

  private void pozisyonBelirle(Keys keyData)
        {
            switch (keyData)
            {
                case yukari:
                    if (yon != yonEnum.Asagi)
                        yon = yonEnum.Yukari;
                    break;
                case asagi:
                    if (yon != yonEnum.Yukari)
                        yon = yonEnum.Asagi;
                    break;
                case sola:
                    if (yon != yonEnum.Saga)
                        yon = yonEnum.Sola;
                    break;
                case saga:
                default:
                    if (yon != yonEnum.Sola)
                        yon = yonEnum.Saga;
                    break;
            }
        }

Ve poizsyonumuzu belirliyoruz

  private void pozisyonBelirle()
        {
            switch (yon)
            {
                case yonEnum.Asagi:
                    posY++;
                    break;
                case yonEnum.Yukari:
                    posY--;
                    break;
                case yonEnum.Sola:
                    posX--;
                    break;
                case yonEnum.Saga:
                default:
                    posX++;
                    break;
            }
        }

Yem oluşturma ve yeme fonksiyonlarımızı yazıyoruz

   private void yemOlustur()
        {
            Random random = new Random(DateTime.Now.TimeOfDay.Milliseconds);
            int x = 0;
            int y = 0;
            bool b = true;

            while (b)
            {
                x = random.Next(xMin, xMax + 1) * multiplier;
                y = random.Next(yMin, yMax + 1) * multiplier;

                b = poizsyon.Any(t => t.X == x && t.Y == y);
            }

            bait = new Point(x, y);
        }

        private void eatBait()
        {
            Point lastPoint = poizsyon[poizsyon.Count - 1];
            poizsyon.Add(new Point(lastPoint.X, lastPoint.Y));
            puan += (cmbHiz.SelectedIndex + 1) * 10;
            cizim();
            yemOlustur();
        }

Çizim ve oyun başlatma fonksiyonlarımızı yazıyoruz

  private void cizim()
        {
            lbPuan.Text = puan.ToString();
            lbYem.Text = (poizsyon.Count - 3).ToString();
        }
        private void basla()
        {
            cmbHiz.Enabled = false;
            bntBasla.Enabled = false;
            hizAyarla();
            gameTimer.Enabled = true;
        }

        private void oyna()
        {
            pozisyonBelirle();
            bool isGameEnded = oyunBitti();

            if (isGameEnded)
            {
                gameTimer.Enabled = false;
                MessageBox.Show(String.Format("Oyun Bitti! Puanınız: {0}", puan),
                                "Game Over", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            if (posY > yMax)
                posY = yMin;
            else if (posY < yMin) posY = yMax; if (posX > xMax)
                posX = xMin;
            else if (posX < xMin)
                posX = xMax;

            poizsyon.Insert(0, new Point(posX, posY));
            poizsyon.RemoveAt(poizsyon.Count - 1);

            if (bait.X == posX * multiplier && bait.Y == posY * multiplier)
            {
                eatBait();
            }

            yilanCiz();
            lastKeyProcessed = true;
        }

Nokta çizme ve yılanı çizme fonksiyonlarımızı yazıyoruz

  private void noktaCiz(int x, int y, bool isBlack = true)
        {
            using (Graphics g = this.gameArea.CreateGraphics())
            {
                Color penColor = isBlack ? Color.Green : Color.Orange;
                Pen pen = new Pen(penColor, 5);
                g.DrawRectangle(pen, x, y, 5, 5);
                pen.Dispose();
            }
        }

        private void yemCiz()
        {
            noktaCiz(bait.X, bait.Y, false);
        }
        private void yilan_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < 6; i++)
                cmbHiz.Items.Add(i + 1);
            cmbHiz.SelectedIndex = 2;
        }

Butonlara oyunu başlama ve sıfırlama işlevlerini veriyoruz ve bitiriyoruz.

       private void bntBasla_Click(object sender, EventArgs e)
        {
            oyunSifirla();
            basla();
        }

        private void btnSifirla_Click(object sender, EventArgs e)
        {
            oyunSifirla();
        }

Oyunun Çalışırken ki görüntüsü

Projeyi kaynak kodlarına buradan ulaşabilirsiniz.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir