Top sekme oyununun 2. versiyonunda form kenarlarından sekmeye ek olarak engel olarak tanımlanan bir nesneden sekme işlemi de gerçekleştirilmiştir.
Bu yazıya başlamadan önce Top Oyunu v1 – Form Kenarlarından Seken Top başlıklı yazıya bakmanız, bu versiyonda yaptığımız değişiklikleri daha iyi anlayabilmeniz için önemlidir.
Top olarak nitelenen kare isimli butonun bir engele çarpması, 4 şekilde mümkün olmaktadır:
- Engelin solundan çarpma
- Engeline sağından çarpma
- Engele üstten çarpma
- Engele alttan çarpma
Dolayısıyla geliştirilecek algoritmada bu durumlar göz önünde bulundurulacaktır.
Karenin Engel ile Yatayda Aynı Hizada Olması
Engele sağdan ve soldan çarpma durumunda, karenin engel ile yatay olarak aynı hizada olması gerekmektedir. Diğer bir deyişle, aşağıdaki görselde sarı ile gösterilen sınırlar dahilinde kalmalıdır. Bunun için sağlanması gereken şartlar aşağıda gösterilmiştir:
- Bunun için de karenin altı, engelin üstünden büyük bir değere sahip olması gerekir. (kare.Bottom >= engel.Top)
- Benzer şekilde, karenin üst noktası, engelin alt noktasından daha düşük olmalıdır. (kare.Top <= engel.Bottom)
Engele Soldan Çarpma
Engele soldan çarpan kare nesnesi için yukarıdaki görsel daha anlatıcı olacaktır.
kare’nin engele soldan çarptığının anlaşılabilmesi için sağlanması, yatay olarak aynı hizada olmasının dışında sağlanması gereken 2 şart daha vardır. Engele soldan çarpmak demek, engelin sağa doğru hareket ediyor olmasıyla mümkündür.
- Yukarıdaki şekilde de görüldüğü gibi, sağa doğru hareket ettiğinden kare isimli butonun yatayYon değeri +1 olmalıdır.
- karenin sağ tarafının konumu (kare.Right) ile engelin sol tarafının konumu (engel.Left) birbirine eşit olmalıdır. (kare.Right == engel.Left)
Yukarıdaki durumlarının hepsinin birden sağlandığı durumlarda, kare isimli butonun engel isimli Panel nesnesine soldan çarptığı tespit edilir ve bu aşamadan sonra kare, sola doğru hareket etmeye başlamalıdır. Dolayısıyla yatayYon değişkeni yalnızca -1 ile çarpılır ve bu değişkenin işareti değiştirilir. Her bir tetiklemede kare nesnesinin Left değerine yatayYon ilave edildiğinden, yatayYon değerinin -1 olmasıyla kare nesnesi sola doğru hareket etmeye başlar.
Çarpışma gerçekleştiğinde yapılması gereken işlem kısaca şu şekildedir:
1 | yatayYon *= -1; |
Engele Sağdan Çarpma
kare’nin engele sağdan çarpması için öncelikle kare ve engel yine yatayda aynı hizada olmalıdır. Ardından sağlanması gereken şartlar şunlardır:
- Eğer kare sola doğru hareket ediyorsa çarpışma ihtimali vardır. Yani yatayYon değişkeni -1 olmalıdır.
- Karenin sol sınırı (kare.Left) ile engelin sağ sınırı (engel.Right) aynı hizaya gelmelidir. (kare.Left == engel.Right)
Bu şartların sağlanmasıyla karenin yatay yönü -1 ile çarpılır.
1 | yatayYon *= -1; |
Karenin Engel ile Dikeyde Aynı Hizada Olması
Karenin dikeyde aynı hizaya gelebilmesi için aşağıdaki şartların sağlanması gerekmektedir:
- karenin sağ konumu, engelin sol konumundan daha büyük bir değere sahip olmalıdır. (kare.Right >= engel.Left)
- karenin sol konumu, engelin sağ konumundan daha küçük bir değere sahip olmalıdır. (kare.Left <= engel.Right)
Bu durumlar sağlanıyorsa, karenin engele üstten veya alttan çarpma durumları ayrı ayrı değerlendirilir.
Engele Üstten Çarpma
Engele üstten çarpma durumunun anlaşılabilmesi için aşağıdaki görsel daha açıklayıcı olacaktır.
Dikeyde aynı hizaya gelmenin yanında aşağıdaki 2 şart da sağlanıyorsa engele üstten çarpma gerçekleşmiştir:
- karenin dikeyYon değeri 1 olmalıdır, yani engelin üstünden temas edecekse karenin aşağıya doğru hareket etmesi gereklidir. (dikeyYon == 1)
- karenin altı ile engelin üstü aynı hizaya gelmelidir. (kare.Bottom == engel.Top)
Yukarıdaki 2 durumun da gerçekleşmesi halinde kare, artık aşağıya değil yukarıya doğru hareket etmelidir. Bunun için aşağıdaki dikeyYon değeri -1 ile çarpılır.
1 | dikeyYon *= -1; |
Engele Alttan Çarpma
Engele alttan çarpma durumu için aşağıdaki şartların sağlanması gereklidir:
- kare, yukarıya doğru hareket halinde olmalıdır. (dikeyYon == -1)
- kare, engele alttan temas etmelidir. Yani karenin üstü (kare.Top) ile engelin altı (engel.Bottom) aynı hizada olmalıdır. (kare.Top == engel.Bottom)
Bu şartların sağlanmasıyla topun dikey yönü -1 ile çarpılır.
1 | dikeyYon *= -1; |
Engele Çarpışma C# Kodları
Top Oyunu v1 – Form Kenarlarından Seken Top isimli yazıya ek olarak timer1 içerisine yazılması gerekene kodlar şu şekildedir:
1 2 3 4 5 6 7 8 9 10 11 | //YATAYDA AYNI HİZA if (kare.Bottom >= engel.Top && kare.Top <= engel.Bottom) { //ENGELİN SOLUNDAN ÇARPMA if (yatayYon == 1 && kare.Right == engel.Left) yatayYon *= -1; //ENGELİN SAĞINDAN ÇARPMA if (yatayYon == -1 && kare.Left == engel.Right) yatayYon *= -1; } |
Yukarıdaki kodlarda dikkat edilirse hem soldan hem de sağdan çarpma durumunda yatayYon değişkenini -1 ile çarpıyoruz, yani aynı işi yapıyoruz. Bu durumda bu şartların da VEYA ile birleştirilmesi mümkündür.
1 2 3 4 5 6 7 8 9 10 11 12 13 | //YATAYDA AYNI HİZA if (kare.Bottom >= engel.Top && kare.Top <= engel.Bottom) { //ENGELİN SOLUNDAN VEYA SAĞINDAN ÇARPMA if ( (yatayYon == 1 && kare.Right == engel.Left) || (yatayYon == -1 && kare.Left == engel.Right) ) { yatayYon *= -1; } } |
Bu gibi şartları birleştirmek mantıklı olsa da kod okunabilirliği ciddi ölçüde azalmaktadır. Yukarıdaki iki blok da aynı işi yapıyor olsa da programcı, kolay anlaşılabilir olan kodları tercih etmek isteyebilir.
Yukarıdaki kodlara ek olarak aşağıdaki kodlar da üst veya alttan çarpma durumlarını ifade eder:
1 2 3 4 5 6 7 8 9 10 11 | //DİKEYDE AYNI HİZA if (kare.Right >= engel.Left && kare.Left <= engel.Right) { //ENGELİN ÜSTÜNDEN ÇARPMA if (dikeyYon == 1 && kare.Bottom == engel.Top) dikeyYon *= -1; //ENGELİN ALTINDAN ÇARPMA if (dikeyYon == -1 && kare.Top == engel.Bottom) dikeyYon *= -1; } |
Sonuç
Top oyununun 2. versiyonu sonucunda Form içindeki kodlar şu şekilde olmaktadır:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace ButonCarpisma { public partial class Form1 : Form { public Form1() { InitializeComponent(); } int dikeyYon = 1, yatayYon = 1; private void timer1_Tick(object sender, EventArgs e) { kare.Left += yatayYon; kare.Top += dikeyYon; if (kare.Right >= this.Width || kare.Left <= 0) yatayYon *= -1; if (kare.Bottom >= this.Height || kare.Top <= 0) dikeyYon *= -1; // ### ENGELLE ÇARPIŞMA ### //YATAYDA AYNI HİZA if (kare.Bottom >= engel.Top && kare.Top <= engel.Bottom) { //ENGELİN SOLUNDAN VEYA SAĞINDAN ÇARPMA if (yatayYon == 1 && kare.Right == engel.Left) yatayYon*=-1; if (yatayYon == -1 && kare.Left == engel.Right) yatayYon *= -1; } //DİKEYDE AYNI HİZA if (kare.Right >= engel.Left && kare.Left <= engel.Right) { //ENGELİN ÜSTÜNDEN ÇARPMA if (dikeyYon == 1 && kare.Bottom == engel.Top) dikeyYon *= -1; //ENGELİN ALTINDAN ÇARPMA if (dikeyYon == -1 && kare.Top == engel.Bottom) dikeyYon *= -1; } } private void Form1_DoubleClick(object sender, EventArgs e) { this.Close(); } } } |