Merhabalar, internette gezinirken bir C# uçak savaş oyunu uygulamasına denk geldim. Ancak uygulamayı incelediğimde bana çok sade geldi. Bende o uygulamayı alıp daha geliştirerek yeni özellikler eklemek istedim.
C# Uçak Savaş Oyunu Yapımı
İlk halinde can kavramı yoktu ve ilk yanışta oyun bitiyordu. Ayrıca yanma durumu da sadece düşman uçağın formdan çıkması ile oluyordu. Oyunun ilk haline ek olarak
- Yanma durumu, düşman uçak ile oyuncu uçağın çarpışmasına da eklendi.
- 5 can ile başlama ile yandığında can azalması ve 5 defaya mahsus olmak üzere her 100 puanda +1 can ekleme…
- Oyuna 3 farklı zorluk seviyesi…
- Düşman uçağın ortasından (mükemmel +50) yada kanatlarından(güzel +10) vurulma konumuna göre farklı puanların verilmesi…
- Vuruş konumundan gelen puan ve durumun labeller ile gösterilmesi. Gösterim şekli, mermi ile düşman uçağın buluştuğu noktada görünür olup yukarı doğru giderek kaybolması…
Şeklinde 5 yeni özellik ekledim. Tabi bunlar o kadar da kolay olmadı diyebilirim. Kaldı ki bana kopyacı demeyi düşünen arkadaşlara söylemek isterim ki, hiçbir ekleme yapılmamış olan halini de zaten yapabilirim ve zamanında bir çok benzer oyun yapmıştım. Bu oyun uygulamasını gördükten sonra üzerine biraz daha ekleyip hakkında yazı yazmak istedim.
Aslında bu dersin amacı bir oyun paylaşmak değil. Zira böyle dandik bir oyunu kim oturup oynar değil mi? Benim buradaki amacım, nesnelerin koordinatları üzerinde çalışmak, bir kaç nesneyi daha iyi anlayabilmek ve kullanım şekilleri hakkında fikirler vermektir.
Neyse daha fazla uzatmadan yavaştan kodlarımızı verelim. Kodlara geçmeden önce bir ekran görüntüsünü vereyim. Tasarımın nasıl olduğunu görün.
NOT: Bu proje hali hazırda Github’da yüklü. Ancak bunun üzerinde biraz daha çalışmak istediğim için hem Github hemde Drive üzerinden linkler vereceğim. Bu yazıdaki projeyi aynen içeren versiyonu Drive üzerinde olacak. Güncellenmiş hali de Github üzerinde olacak.
Oyunun Kodları
Değişkenler
Random rnd = new Random(); int solHareket = 0, ducakHareketHiz = 3, mermiHiz = 8, can = 5, Puan = 0, mukemmel_zorluk = 20, iyi_puan = 10, muk_puan = 50, ekcan = 1; bool yandi = false;
- Random, düşman uçaklarının başlama noktalarını değiştirmek için
- SolHareket, uçağımızın hareket hızı
- ducakHareketHiz, düşman uçak hareket hızı
- mermiHiz, merminin hızı
- can, başlangıç canı
- puan, oyun puanı
- mukemmel_zorluk, mükemmel alabilmek için gerekli uzaklık
- iyi_puan, güzel vuruş puanı
- muk_puan, mükemmel vuruş puanı
- ekcan, alınan canı ifade ediyor.
Değişken olarak birde nesnemiz var.
private PictureBox p_can() { PictureBox p_can = new PictureBox(); p_can.Image = global::Ucak_Savasi.Properties.Resources.can; p_can.SizeMode = PictureBoxSizeMode.StretchImage; p_can.Size = new Size(20, 20); return p_can; }
Can olarak gösterilecek kalp resmi olan picturebox nesnesi dinamik olarak üretileceğinden bir sınıf hazırladık.
NOT: Şuanda düşman uçaklar dinamik olarak üretilmiyor. İleride düşman uçaklarını da dinamik olarak ürettireceğim.
Constuctor Metodu
public Form1() { InitializeComponent(); // düşman uçağını formun dışına atıyoruz dusman_1.Top = -500; dusman_2.Top = -900; dusman_3.Top = -1300; //farklı olmalarının sebebi aynı anda ekrana gelmesinler. // labelleri formun dışına atıyoruz. lbl_durum.Top = -100; lbl_puan.Top = -100; // mermiyi formun dışına atıyoruz. mermi.Top = -100; mermi.Left = -100; }
Burada düşman uçakları, mermi ve labelleri formun dışına atıyoruz. Başlangıçta görünmelerini istemiyoruz.
Form Load Eventi
private void Form1_Load(object sender, EventArgs e) { for (int i = 0; i < 5; i++) flowLayoutPanel1.Controls.Add(p_can()); }
Burada döngü ile 5 adet can ekliyoruz. Bu canlar dinamik olarak üretilen içerisinde kalp resmi olan picturebox’lardır. Yukarıdaki picturebox üreten metodumuzu kullanıyoruz. Ayrıca dinamik olarak üretilen can picturebox’ların Location özelliklerini ayarlamak için bir sürü hesaplama yapmak istemediğimden flowlayoutpanel kullandım. Bağlantılarda ilgili konular hakkında diğer yazılarıma ulaşabilirsiniz..
NOT: FlowLayoutPanel nesnesinin FlowDirection özelliği TopDown’dur.
Form KeyDown Eventi
private void Form1_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { basla(); // ENTER tuşu ile başlar } if (e.KeyCode == Keys.S) { oyunSonu(); // S, STOP tuşu ile oyun biter. } if (e.KeyCode == Keys.Left) // sol oka bastığmızda sola gidecek { if (player.Location.X < 0) //eğer çok fazla gidipte formdan çıkarsa { solHareket = 0; player.Location = new Point(0, 498); // orada kalsın. X (yatay) koordinatta formdan çıkamasın. } else { solHareket = -10; // from sınırlarını aşmıyorsa -10 yani sola gitsin } } else if (e.KeyCode == Keys.Right)// sağ oka bastığmızda sağa gidecek { if (player.Location.X > 512)//eğer çok fazla gidipte formdan çıkarsa { player.Location = new Point(512, 498);// orada kalsın. X (yatay) koordinatta formdan çıkamasın. solHareket = 0; } else { solHareket = 10;// from sınırlarını aşmıyorsa +10 yani sağa gitsin } } else if (e.KeyCode == Keys.Space) // boşluk tuşu ateş eder. { mermiHiz = 60; // merminin hızı mermi.Left = player.Left + 40; // mersinin görsel olarak çıkacağı yer. Uçağın ortasından; mermi.Top = player.Top; // mersinin görsel olarak çıkacağı yer. Uçağın ucundan; } }
Burada form açıkken tıklanan tuşlara göre yapılacak işlemler yer almaktadır. player = oyuncunun kontrol ettiği uçak
- ENTER, oyunu başlatır.
- S, oyunu durdurur.
- Sol Ok, eğer oyuncu uçağı formun en soluna gelmiş ise formdan dışarı çıkmaması için, hareket hızın sıfırlayıp, formun X (yatay) koordinatında 0. koordinatı geçememesini sağladık.
- Sağ Ok, eğer oyuncu uçağı formun en sağına gelmiş ise formdan dışarı çıkmaması için, hareket hızın sıfırlayıp, formun X (yatay) koordinatında 512. koordinatı yani formun genişliğini geçememesini sağladık.
- Space, oyuncu uçağının ateş etmesini sağladık. Mermi resmi olan picturebox’ın sol kenarı, oyuncu uçağının picturebox’ının sol kenarından sağa doğru 40 piksel içeriden başlamasını yani oyuncu uçağının ortasından çıkmasını istedik.
Form KeyUp Eventi
private void Form1_KeyUp(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Left) // sol ok tuşuna artık basılmıyorsa hızı kes { solHareket = 0; } else if (e.KeyCode == Keys.Right) // sağ ok tuşuna artık basılmıyorsa hızı kes { solHareket = 0; } }
Elimizi ok tuşlarından çektiğimizde hareketin durmasını istedik.
Nesnelerin Click Eventleri
private void oyunaBaşlaToolStripMenuItem_Click(object sender, EventArgs e) { basla(); } private void oyunuBitirToolStripMenuItem_Click(object sender, EventArgs e) { oyunSonu(); } private void zorToolStripMenuItem_Click(object sender, EventArgs e) { zorToolStripMenuItem.Checked = true; ortaToolStripMenuItem.Checked = false; kolayToolStripMenuItem.Checked = false; rad_zor.Checked = true; } private void ortaToolStripMenuItem_Click(object sender, EventArgs e) { zorToolStripMenuItem.Checked = false; ortaToolStripMenuItem.Checked = true; kolayToolStripMenuItem.Checked = false; rad_orta.Checked = true; } private void kolayToolStripMenuItem_Click(object sender, EventArgs e) { zorToolStripMenuItem.Checked = false; ortaToolStripMenuItem.Checked = false; kolayToolStripMenuItem.Checked = true; rad_kolay.Checked = true; } private void btn_basla_Click(object sender, EventArgs e) { basla(); } private void btn_duraklat_Click(object sender, EventArgs e) { oyunSonu(); }
Formdaki görünen başla ve bitir butonlarının click eventleri…
ContextMenuStrip nesnesindeki (sağ tık menüsü) buttonların click eventleri.
Burada ek olarak daha önce hiç bahsetmediğim ve yeni öğrendiğim bir özellik var. ContextMenuStrip nesnesindeki menüleri checkbox şeklinde kullanabiliyoruz.
Yukarıdaki görsel oyunu çalıştırdığımızda karşımıza gelen ekrandır. ContextMenuStrip nesnesindeki zorluk kısmındaki Orta menüsünün yanındaki check işaretini görebiliyorsunuz değil mi? Bu şekilde ContextMenuStrip nesnesindeki menüleri checkbox şeklinde kullanabiliyoruz.
Checkbox şeklinde çalıştığı için aynı anda hepsi yada ikisi seçili olmaması için birini seçtiğimizde diğerlerinin işaretinin kalkması gerekiyor. Bu sebeple ContextMenuStrip nesnesindeki menülerin click eventlerinde birini işaretlediğimizde diğerlerini kaldırıyoruz. Ayrıca bu ContextMenuStrip ‘i sonradan eklediğim için, ekrandaki radiobuttonları kaldırmak yerine yine click eventlerinde seçilene göre bir işaretleme yaptım. En azından ekranda aktif zorluk seviyesinin görünmesini istedim.
Aslında ilk önce üst paneldeki buttonlar ve radiobuttonlar aktifti. Ancak başla buttonuna tıklayıp oyunu başlattıktan sonra panelin enabled özelliği false yaptığımda her space tuşuna bastığımda dlink dlink dlink diye ötüyordu. Bu yüzden onları silmeden direk panelin enabled özelliği false yaptım ve contextmenustrip ‘i ekledim. Şimdi dlink dlink dlink ses çıkmıyor. :D
Basla Metodu
private void basla() { // oyunu sıfırlıyoruz. Başlangıçta nasılsa o hale gelecek. dusman_1.Top = -500; dusman_2.Top = -900; dusman_3.Top = -1300; mermi.Top = -100; mermi.Left = -100; can = 5; player.Location = new Point(258, 498); kolayToolStripMenuItem.Enabled = false; ortaToolStripMenuItem.Enabled = false; zorlukToolStripMenuItem.Enabled = false; oyunaBaşlaToolStripMenuItem.Enabled = false; oyunuBitirToolStripMenuItem.Enabled = true; // seçilen zorluğa göre düşman uçaklarının hızını ayarlıyoruz. if (kolayToolStripMenuItem.Checked == true) ducakHareketHiz = 2; if (ortaToolStripMenuItem.Checked == true) ducakHareketHiz = 5; if (zorlukToolStripMenuItem.Checked == true) ducakHareketHiz = 7; panel1.Enabled = false; timer1.Start(); }
- He basla metodu çalıştığında düşman uçaklar ve mermi formun dışarısına atılır.
- Oyuncu uçağı ekranın ortasına getirilir.
- ContextMenuStirp nesnesindeki diğer menüler pasif edilir. ( İki kere basla metodu çalışmasın, oyun aktifken zorluk değiştirilmesin diye…)
- Seçilmiş olan zorluğa göre düşman uçaklarının hızlarını ayarladık.
- Paneli pasif yaptık
- Timer ‘ı çalıştırdık.
NOT: Oyunun temelinde Timer nesnesi vardır. Nesneleri oyun mantığına göre hareket ettirebilecek tek nesne Timer’dır. En azından benim bildiğim kadarı ile öyle. :) Başka yolunu bilen varsa yorumlara yazabilse memnun olurum. :)
OyunSonu Metodu
private void oyunSonu() { // oyun biter, bildirimverişir herşey sıfırlanır timer1.Stop(); timer1.Enabled = false; dusman_1.Top = -500; dusman_2.Top = -900; dusman_3.Top = -1300; mermi.Top = -100; mermi.Left = -100; MessageBox.Show("Oyun Bitti! - " + Puan + " Puan Kazandınız....", "Uçak Oyunu V1.0 www.bilisimogretmeni.com", MessageBoxButtons.OK, MessageBoxIcon.Stop); Puan = 0; lblsonuc.Text = "0"; panel1.Enabled = true; oyunaBaşlaToolStripMenuItem.Enabled = true; kolayToolStripMenuItem.Enabled = true; ortaToolStripMenuItem.Enabled = true; zorlukToolStripMenuItem.Enabled = true; oyunuBitirToolStripMenuItem.Enabled = false; }
- Timer durur
- Düşman uçakları ve mermi form duşuna atılır.
- Durum mesajı verilir.
- Puan sıfırlanır
- Panel açılır
- ContextMenuStrip nesnesi menüleri aktif edilir. Bitir hariç.
Can Ekleme Metodları
private void can_ekle() { if (Puan > 100 && ekcan == 1) { can++; ekcan = 2; canlar(); } if (Puan > 200 && ekcan == 2) { can++; ekcan = 3; canlar(); } if (Puan > 300 && ekcan == 3) { can++; ekcan = 4; canlar(); } if (Puan > 400 && ekcan == 4) { can++; ekcan = 5; canlar(); } if (Puan > 500 && ekcan == 5) { can++; ekcan = 6; canlar(); } }
Burada, istediğim mantığı tam oturtamadım. Burada yapmak istediğim her 100 puanda bir can kazanılabilmesi… Şimdilik yapamadığım için her 100 puan için sadece bir kere olmak üzere toplamda 5 can verdiriyorum.
private void canlar() // canların azalması ve kalplerin kaybolması { flowLayoutPanel1.Controls.Clear(); for (int i = 0; i < can; i++) { flowLayoutPanel1.Controls.Add(p_can()); } }
Burada, can ekle metodu ile arttırdığımız can sayısına göre flowlayoutpanel’e can picturebox’ları ekleyen for döngüsü vardır.
Sadece burada dinamik nesne ve flowlayoutpanel kullanmasaydık. Yani 10 tane picturebox kullansaydık yapacağımız kod hammallığını siz düşünün artık.
10 tane picturebox olacak biri gelecek biri gidecek, Can durumuna göre picturebox’ların Location’larını sürekli değiştirmemiz gerekecek vs. vs.
Vurma Metodu – Düşman Uçakları Vurmak
private void Vurulma() { if (mermi.Bounds.IntersectsWith(dusman_1.Bounds)) // mermi düşman uçak 1 e değdi ise { // eğer mermi, düşman uçaklrının tam ortasına değdi ise 2 puan, kanatlarına değdi ise 1 puan verilecek. // Bu sebeple merminin nereye değdiğini bulmamaız gerekiyor. int ucde_biri; ucde_biri = dusman_1.Width / 3; int left = dusman_1.Left; int right = dusman_1.Right; // burada amacımız puan ve durum labelleri ateş ile uçağın çarpışma noktasına gidip oradan // yukarı çıkarak kaybolması lbl_puan.Location = mermi.Bounds.Location; lbl_durum.Location = new Point(mermi.Bounds.Location.X, mermi.Bounds.Location.Y + 25); // mükemmel puanın aralığını parametrik olarak azalttık. // bu sayede burada istersek, seçilen zorluğua göre mükemmeli de zorlaştırabiliriz. if (mermi.Right < left + ucde_biri + mukemmel_zorluk || mermi.Left > right - ucde_biri - mukemmel_zorluk) { Puan += iyi_puan; lbl_puan.Text = "+" + iyi_puan + " Puan"; lbl_durum.Text = "GÜZEL!"; } else { Puan += muk_puan; lbl_puan.Text = "+" + muk_puan + " Puan"; lbl_durum.Text = "MÜKEMMEL!"; } can_ekle(); dusman_1.Top = -500; // vurulan düşman geriye gider. int ranP = rnd.Next(1, 300); //random bir sayı alır ve dusman_1.Left = ranP; // o hizadan başlar. // Mermi sıfırlanır. mermiHiz = 0; mermi.Top = -100; mermi.Left = -100; } else if (mermi.Bounds.IntersectsWith(dusman_2.Bounds)) { int ucde_biri; ucde_biri = dusman_2.Width / 3; int left = dusman_2.Left; int right = dusman_2.Right; lbl_puan.Location = mermi.Bounds.Location; lbl_durum.Location = new Point(mermi.Bounds.Location.X, mermi.Bounds.Location.Y + 25); if (mermi.Right < left + ucde_biri + mukemmel_zorluk || mermi.Left > right - ucde_biri - mukemmel_zorluk) { Puan += iyi_puan; lbl_puan.Text = "+" + iyi_puan + " Puan"; lbl_durum.Text = "GÜZEL!"; } else { Puan += muk_puan; lbl_puan.Text = "+" + muk_puan + " Puan"; lbl_durum.Text = "MÜKEMMEL!"; } can_ekle(); dusman_2.Top = -900; int ranP = rnd.Next(1, 400); dusman_2.Left = ranP; mermiHiz = 0; mermi.Top = -100; mermi.Left = -100; } else if (mermi.Bounds.IntersectsWith(dusman_3.Bounds)) { int ucde_biri; ucde_biri = dusman_3.Width / 3; int left = dusman_3.Left; int right = dusman_3.Right; lbl_puan.Location = mermi.Bounds.Location; lbl_durum.Location = new Point(mermi.Bounds.Location.X, mermi.Bounds.Location.Y + 25); if (mermi.Right < left + ucde_biri + mukemmel_zorluk || mermi.Left > right - ucde_biri - mukemmel_zorluk) { Puan += iyi_puan; lbl_puan.Text = "+" + iyi_puan + " Puan"; lbl_durum.Text = "GÜZEL!"; } else { Puan += muk_puan; lbl_puan.Text = "+" + muk_puan + " Puan"; lbl_durum.Text = "MÜKEMMEL!"; } can_ekle(); dusman_3.Top = -1300; int ranP = rnd.Next(1, 500); dusman_3.Left = ranP; mermiHiz = 0; mermi.Top = -100; mermi.Left = -100; } }
Elimizde 3 tane fiziksel olarak picturebox ile düşman uçağı olduğu için, her biri için işlemler yapmamız gerekiyor. Bu sebeple burası biraz uzun…
- İf içerisine baktığımızda, mermiyi çevreleyen çizgiler ile düşman uçağını çevreleyen çizglerin birbirlerine değip değmediğini kontrol ediyoruz.
- Bir int değişken tanımladık.
- Bu değişkene düşman uçağını temsil eden picturebox’un üçte birini aldık. 100 pixsel ise 33 piksel olur.
- Düşman uçağını temsil eden picturebox’un sağ ve sol kenarlarının koordinatlarını aldık.
- Left, Righti Top, Bottom koordinat bilgisidir.
- Vuruştan gelen puanı gösterecek olan labelimizin konumunu, merminin konumuna getirdik.
- Vuruştan gelen vuruş durumunu gösterecek olan labelimizin konumunu, merminin konumuna getirdik. Ancak üst üste gelmemesi için durum labelini, puan labelinin 25 piksel altına getirdik.
- Dikeyde (Y) + demek aşağı inmek demektir.
- Mermi picturebox’ının sağı, düşman uçağının solu + düşman uçağının boyutunun üçte biri + mükemmel zorluk piksellerinin toplamından büyükse ve merminin solu, düşman uçağının sağı – düşman uçağının üçte biri – mükemmel zorluk toplamından küçükse arada kalan kısım mükemmel alanıdır.
Son maddeyi daha net anlayabilmeniz için paintte bir görsel hazırladım. :)
- Mükemmel alanından vuruldu ise 50, mükemmel alanı dışından vuruldu ise 10 puan verilecek.
- Vurulma işleminde puan artacağından kontrol için canekle metodunu çağırdık
- düşman uçağını -1300 piksel yukarı gönderdik. Yani formdan kovduk.
- Random sayı ile vurulduğu hizadan gelmemesi için bir konum belirledik.
- Mermi sıfırlandı.
Timer Tick Eventi
private void timer1_Tick(object sender, EventArgs e) { // NOT: Timer1'in İnterval'i 10'dur. Tuşlar saniyede 100 defa kontrol ediliyor player.Left += solHareket; // oyuncu uçağının koordinatını, tuşa basılı olduğu sürece değiştir. mermi.Top -= mermiHiz; // mermi hızı arttırılıyor. NOT: Mermi yukarı gittiğinden dolayı azalması gerekiyor. - değil de + olursa mermi formun altına gider. dusman_1.Top += ducakHareketHiz; // düşman uçaklarının hareketi sağlanıyor. dusman_2.Top += ducakHareketHiz; // düşman uçaklarının hareketi sağlanıyor. dusman_3.Top += ducakHareketHiz; // düşman uçaklarının hareketi sağlanıyor. lblsonuc.Text = "" + Puan; // puanı yazdık if (can > 0) // canlarımız tükenmediyse... { if (dusman_1.Bottom >= player.Top + player.Height / 2) // düşman uçağının alt çizgisi, player'in yarısına kadar gelmiş ise { if ((dusman_1.Right > player.Left && dusman_1.Right < player.Right) || (dusman_1.Left > player.Left && dusman_1.Left < player.Right)) // Düşman uçağının sağ çizgisi; player uçağının sol çizgisininden içeri girmişse yada player uçağının sağ çizgisininden içeri girmiş ise // Yani düşman uçağının sağ çizgisi ya da sol çizgisi, player uçağınına değmiş ise // Yani bir çarpışma var ise { dusman_1.Top = -500; yandi = true; can--; canlar(); } } else if (dusman_2.Bottom >= player.Top + player.Height / 2) { if ((dusman_2.Right > player.Left && dusman_2.Right < player.Right) || (dusman_2.Left > player.Left && dusman_2.Left < player.Right)) { dusman_2.Top = -900; yandi = true; can--; canlar(); } } else if (dusman_3.Bottom >= player.Top + player.Height / 2) { if ((dusman_3.Right > player.Left && dusman_3.Right < player.Right) || (dusman_3.Left > player.Left && dusman_3.Left < player.Right)) { dusman_3.Top = -1300; yandi = true; can--; canlar(); } } if (dusman_1.Bottom >= 630) // eğer düşman uçak player uçağa çarpmamış ama onu geçmiş gitmiş ise.. { dusman_1.Top = -500; yandi = true; can--; canlar(); } else if (dusman_2.Bottom >= 630) { dusman_2.Top = -900; yandi = true; can--; canlar(); } else if (dusman_3.Bottom >= 630) { dusman_3.Top = -1300; yandi = true; can--; canlar(); } } else { oyunSonu(); // can biterse oyun biter } // labeller çarpışma noktasına giderek ve yukarı doğru çıkarak kaybolacak. lbl_puan.Top -= 5; lbl_durum.Top -= 5; Vurulma(); // düşman uçağı vurma }
- Burada, ilk satırlardaki kodlar nesnelerin Top ve Left koordinatlarına += ile ekleme yada -= ile çıkarma yapıldığından dolayı nesneler form üzerinde hareket edebiliyor.
- Can 0 değil ise
- Düşman uçağının alt kenarı, oyuncu uçağının üst kenar çizgisi – oyuncu uçağı yüksekliğinin yarısının koordinatına gelmiş ise… (Yani düşman uçak, oyuncu uçağının yarısına kadar indi ise)
- Düşman yenildi ancak bir can kaybettik.
- Her düşman için tekrarlandı.
- Düşman uçak, formun en altına ulaştı ise
- Düşman kayboldu ve can kaybettik.
- Her düşman için tekrarlandı.
- Düşman uçağının alt kenarı, oyuncu uçağının üst kenar çizgisi – oyuncu uçağı yüksekliğinin yarısının koordinatına gelmiş ise… (Yani düşman uçak, oyuncu uçağının yarısına kadar indi ise)
- Can 0 ise oyun biter.
- Vurulma anında ortaya çıkan labeller formun yukarısına doğru akar
- Vurulma var mı kontrol edilir.
Huuuu.. Yazıyı bitirmem neredeyse 2,5 saatimi aldı. Oyunun hepsi şimdilik bu kadar arkadaşlar. Dediğim gibi, siz bu dersi gördüğünüzde github’daki hali farklı olabilir bu sebeple projeyi Drive’a yükleyip ayrıca bir indirme linki vereceğim ki bu yazıdaki haline ulaşabilesiniz.
Giriş kısmında da bahsettiğim gibi, burada olan oyunun kendisi değil, oyunu yazarken kullandığımız yöntemlerdir.
C# Uçak Savaş Oyunu Yapımı Projesinin Bana Faydaları Ne Oldu?
Örneğin bu proje ile uğraşırken contextmenustrip menülerini checkbox gibi kullanmayı öğrendim ve keşke daha önce öğrenseydim dedim çünkü bir çok projemde işlerimi kolaylaştırabilirdi.
Ayrıca flowlayoutpanel konusu kafamda iyice yer etti. Eğer bir yerde dinamik nesne kullanmam ve bunları bir düzene göre sıralamam gerekirse aklıma gelen ilk nesne flowlayoutpanel olacak. Çünkü C# Dinamik Nesne Oluşturma ve Forma Ekleme yazıma giderseniz buttonları bir düzene sokabilmek için ne kadar çabaladığımızı görebilirsiniz. flowlayoutpanel ile bu çabalamaya hiç gerek kalmıyor.
Nesnelerin Location konusu kafamda iyice netleşti.
Çok güzel olmasa da bir oyun geliştirme deneyimi ve c sharp 2d oyun yapmak hakkında az da olsa bilgi edinebildim.
Yapılan Güncellemeler (17.09.2020)
- Mermi ve Düşman Uçak picturebox’ları dinamik olarak üretildi.
- Vurulma anında ufak bir görsellik olması açısından bir patlama görselli picturebox eklendi.
- Savaş Alanı kapsamında bir panel eklendi.
C# uçak savaş oyunu yazımda bu kadar arkadaşlar. Umarım sizler içinde faydalı olmuştur.
C Sharp Eğitim Seti eğitimi sayfasına gitmek için tıklayınız. Derslerime özel olarak hazırladığım Github Projeme buradan ulaşabilirsiniz… Bu dersin Githup Sayfasına buradan ulaşabilirsiniz. Drive’den indirmek isteyenler ise buradan projeye ulaşabilirler.
461. yazı bitti.
uçak savaş oyunu drivede mevcut değil
Merhaba,
Proje zaten drive’da değil ki. Github’da. Yazının en altında da proje linki var.