![]() |
|
|
#1 (permalink) |
|
Paylaşımcı Tayfa
![]() Üyelik tarihi: Dec 2006
Nerden: İstanbul
Mesaj Sayısı: 2.363
Konu Sayısı: 127
Takım: Fenerbahçe
Rep Gücü: 4462
Rep Puanı: 445812
Rep Derecesi :
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
Ruh Hali:
|
Şimdi biz de kendi yılan oyunumuzu yapacağız. Bunun için öncelikle ekranımızı sanal karelere bölmeli ve kaça kaçlık bir ekranda oynamak istediğimizi belirlemeliyiz. Bu örneğin anlatımında ekranı 12 x 8 boyutlarında alacağım. Fakat siz daha geniş bir ekran belirleyebilirsiniz. Ekrandaki bilgileri iki boyutlu bir dizide tutabiliriz. Dim Tablo ( 1 TO 12 , 1 TO 8 ) As Byte Altta 12 x 8'lik tablo (matris) üzerinde 5 birimlik bir yılan görülmektedir. Duvar olması istenen kareler 1 ile, yılan olması istenen karaler (2,3,4,5) ile ve puan olması istenen kare 8 ile gösterilmiştir. Ekranda herhangi bir bilgi içermeyen kareler ise 0 değeri almıştır. Bu sayılar istediğiniz gibi değiştirebilirsiniz. Önemli olan hangi sayının hangi anlamı taşıdığıdır. Bütün oyun boyunca, oyuncunun yaptığı her hareket buradaki bilgilerin değişmesine yol açacaktır. Buradaki bilgilere göre de oyun her seferinde görsel imgelerle oyuncuya bilgi verecektir. Peki niye her objenin 1 adet değeri var da yılan için 4 değer var? Güzel soru. Buradaki değerler yılanın o karedeki hücresinin nereye dönmek istediğini tutar. Yılan, çeşitli yönlere kıvrılabilir ve yılan üzerindeki her kare, kıvrımların nerede olacağı bilgisini taşır. Mesela oyunun hemen başında (yukarıdaki tabloda) yılan DOĞU yönüne gitmektedir. Tabiki yılanın başının ( 8 , 3 ) karesi olduğunu varsayarsak. Yılanın başı ve sonu için yatay-düşey konumlarını tutmalıyız. Sanılanın aksine yılan ekranda hareket ederken bütün kareler güncellenmez. Sadece baş karesi ve son karesi güncellenir. Sizde bunu "aaa.. bak yılan hareket ediyooo" diye seyredersiniz. Yılanın bu 4 verisi haricinde bir de yönü önemlidir. Yön için de bir değişken tutmalıyız. Etti 5 değişken. Bunu kolayca 5 indisli bir tablo ile tutabiliriz. DIM Konum ( 1 TO 5 ) AS BYTE Konum (1) = 8 ' Yılanın Başının Yatay Değeri Konum (2) = 3 ' Yılanın Başının Düşey Değeri Konum (3) = 4 ' Yılanın Sonunun Yatay Değeri Konum (4) = 3 ' Yılanın Sonunun Düşey Değeri Konum (5) = 2 ' Yılanın Yönü , Yılanın yönü için resimdeki yönlere karşılık gelen 2-3-4-5 değerlerini tutabiliriz. HAREKET KONTROLLERİ -------------------------------------------------------------------------------- Yukarıda da bahsettiğim gibi yılanın tüm kareleri hareket etmeyecek. Sadece baş ve son kareleri hareket edecek. Yılan ilerlerken Konum (5) değişkenini kontrol edecek. Bu değişkene göre "İlerlemesi Gereken" karenin hangisi olduğuna bakacak. Bunun için basit SELECT-CASE yapısı kullanılabilir. SELECT Konum (5) CASE 2 : ' Doğu Yönündeki Kare Tablo ( Konum (1) + 1 , Konum (2) ) CASE 3 : ' Güney Yönündeki Kare Tablo ( Konum (1) , Konum (2) + 1 ) CASE 4 : ' Batı Yönündeki Kare Tablo ( Konum (1) - 1 , Konum (2) ) CASE 5 : ' Kuzey Yönündeki Kare Tablo ( Konum (1) , Konum (2) - 1 ) END SELECT Yılanın sağlamca ilerleyebilmesi için önündeki karenin boşluk (sıfır) veya puan (8) olması gerekir. Eğer önündeki kare 1-2-3-4-5 den biri ise oyun biter. Çünkü yılan, duvara veya kendisine çarpmış olur. Yukarıdaki SELECT-CASE yapısını aşağıdaki gibi geliştirelim. SELECT CASE Konum(5) CASE 2 : IF Tablo ( Konum(1) + 1 , Konum(2) ) <> 0 AND Tablo ( Konum(1) + 1 , Konum(2) ) <> 8 THEN ' Yılan Çarptı ELSEIF Tablo ( Konum(1) + 1 , Konum(2) ) = 8 THEN ' Önünde Puan Varsa Puanı Alır. END IF CASE 3 : IF Tablo ( Konum(1) , Konum(2) + 1 ) <> 0 AND Tablo ( Konum(1) , Konum(2) + 1 ) <> 8 THEN ' Yılan Çarptı ELSEIF Tablo ( Konum(1) , Konum(2) + 1 ) = 8 THEN ' Önünde Puan Varsa Puanı Alır. END IF CASE 4 : IF Tablo ( Konum(1) - 1 , Konum(2) ) <> 0 AND Tablo ( Konum(1) - 1 , Konum(2) ) <> 8 THEN ' Yılan Çarptı ELSEIF Tablo ( Konum(1) - 1 , Konum(2) ) = 8 THEN ' Önünde Puan Varsa Puanı Alır. END IF CASE 5 : IF Tablo ( Konum(1) , Konum(2) - 1 ) <> 0 AND Tablo ( Konum(1) , Konum(2) - 1 ) <> 8 THEN ' Yılan Çarptı ELSEIF Tablo ( Konum(1) , Konum(2) - 1 ) = 8 THEN ' Önünde Puan Varsa Puanı Alır. END IF END SELECT "Yılan Çarptı" ve "Puanı Alır" Açıklamalarının olduğu yerlere bunlarla ilgili kodlar yazılır. Eğer yılan çarptıysa ana döngü durdurulur ve "oyun bitti" , "hadi güle güle", "öğrende gel", "yürrrüüü" gibi bitiş mesajları verilebilir. Ben şahsen ilkini hep tercih ederim. Ana döngü dedik de bu ana döngüyü nasıl kurarız. Hemen aklımıza DO-LOOP falan geldi ama timer nesnesi varken DO-LOOP için uğraşmayacağım. Timer nesnesi, içine yazılan kodları sürekli çalıştırır. ENABLE özelliğinin TRUE/FALSE olması ile döngüyü kontrol edebiliriz. Oyun başlarken Timer1.Enabled = False yaparız. Kullanıcı SPACE'e basınca veya istediğiniz bir işlemi gerçekleştirince Timer1.Enabled = True olur. Böylece oyunu başlatma ve durdurma işlemlerini bu nesne ile kolayca yapabiliriz. Hatta oyuna bu şekilde PAUSE durumu da eklemiş oluruz. Ayrıca Timer nesnesinin bir güzel avantajı da döngü hızını belirlememiz ve böylece yılanın hızını ayarlayabilmemiz. INTERVAL özelliği ile kaç milisaniyede tekrarlama yapacağını belirleyebiliriz. Mesela orta hızda bir yılan için 100 değerini tavsiye ederim (saniyede 10 döngü) . Oyun içerisinde bir "Hız Ayar" menüsü ile Timer1.Interval değerini değiştirerek yılanın hızına müdahale edebilirsiniz. Yukarıdaki kodları timer1_Timer özelliği içine koyun. Daha henüz bu kodları geliştireceğiz. Yılanı hareket ettirmek için bizim yapacağımız Konum (5) değişkeninin değerini değiştirmek. Yılan her seferinde (ana döngüde) bu değişkeni kontrol edecek ve sonuç üretecek. Bunun için yılanı çizdireceğimiz picturebox nesnesi üzerinde tuşa basıldığında bu değişkenin değişmesini sağlayabiliriz. ' picturebox nesnesinin adının Ekran olduğunu varsayarak Private Sub Ekran_KeyDown(KeyCode As Integer, Shift As Integer) Select Case KeyCode Case 37: If Konum (5) <> 2 Then Konum (5) = 4 ' Sol Ok Case 38: If Konum (5) <> 3 Then Konum (5) = 5 ' Yukarı Ok Case 39: If Konum (5) <> 4 Then Konum (5) = 2 ' Sağ Ok Case 40: If Konum (5) <> 5 Then Konum (5) = 3 ' Aşağı Ok Case 113: YeniOyunHazirla ' F2 Tuşu Case 19: If Timer1.Enabled = True Then Timer1.Enabled = False Else Timer1.Enabled = True ' Pause Tuşu Case 32: Timer1.Enabled = True ' Space Tuşu End Select End Sub Klavyedeki kontrolleri bu şekilde ekleyebiliriz. Yalnız dikkat edilecek nokta şu. Yılan sağa giderken kullanıcı sol tuşa basarsa yılan bir anda geri gitmeye çalışır ve kendisine çarpmış olur. Bu ihtimali kaldırmak için yılanın yönü kontrol edilerek Konum (5) değişkeni düzenlenir. Yani, Konum (5) eğer 2 den farklıysa 4 olarak değiştir...gibi. YILANIN HAREKET ETMESİNDEKİ ESRAR PERDESİ -------------------------------------------------------------------------------- "Bu camid yılan nasıl oluyor da gidiyor. Hay Allah ya.." diyenler. Yılan, hedefindeki kareyi olumlu olarak gördüğünde evvela bulunduğu karenin değerini "Yeni Yön" değeri ile değiştirir. Mesela (8,3) karesinde iken yön değeri 2 idi. Güneye (8,4) karesine giderken (8,3) karesini 3 yapar. Bunun anlamı bu kareden itibaren "Güneye dönülmüştür" bilgisini kaydetmektir. Ayrıca yeni gitmiş olduğu karenin değerini de 3 yapar. Bu yılanın başının daima yapacağı işlemdir. Ana döngü döndükçe Konum (5) değişkeni sürekli okunur ve yılan ilerler. Puan alımı haricinde yılanın sonu da aynı şekilde davranır. Yılanın son karesi (4,3) olsun. Bu karenin değeri 4 ise, yılan buradan Kuzey yönünde geçmiş. Yani (3,3) karesine gidilecek. Yılanın son karesinin değerleri Konum (3) ve Konum (4) değişkenlerine aktarılır. Önceki (4,3) karesi sıfır yapılır. "Peki puan alınınca yılan nasıl uzuyor? Buna aklım sırrım ermiyor? " diyenler... Tek yapılacak iş puan alınan kareye gelindiğinde yılanın son karesini 1 el bekletmek. Yani yılanın başı yine ilerleyecek ama yılanın son karesi 1 el bekleyecek. RASGELE PUAN KONMASI -------------------------------------------------------------------------------- Randomize ve RND fonksiyonlarını kullanarak 12x8 bir alanda puan koyalım. Yapılacak işlem basit. 10 : Randomize Timer X = FIX (RND * 12) + 1 Y = FIX (RND * 8) + 1 IF TABLO ( X , Y ) = 0 THEN ' Puan konması için karenin boş olması gerekir. TABLO ( X , Y ) = 8 ELSE GOTO 10 ' Tekrar bir konum seç END IF Standart EXE projesi açın. form un scalemodu "3-pixel" olacak 1 adet PictureBox ------------------ Name = Ekran ScaleMod = 3 - Pixel width = 484.................scalewidth = 480 olması için height = 324................scaleheight= 320 olması için tüm colorlar siyah AutReDraw = true 1 adet label ------------ caption = 0 ' puanı yazacağız. 1 adet Timer ------------ enabled = False interval = 100 4 adet image nesnesi --------------------- Bunlar yılan, duvar, puan ve boşluk olacaklar. Paintbrush'ı açın ve 16x16 ebatında siyah zemin üzerine yılan, duvar, puan çizin ve kopyala-yapıştır ile sırasıyla image nesnelerine yapıştırın. boşluk için düz siyah resim yeterli. image nesnelerinin adlarını parca, duvar, bos, yem yapın. visible özelliklerini False yapın. parca : Yılanın 1 karelik parçası duvar : Duvarın 1 karelik parçası bos : Silmek İçin 1 karelik parça yem : Puan için 1 karelik parça Şimdilik basit yapı için bu nesneler yeterli. PictureBox.PaintPicture Özelliği -------------------------------------------------------------------------------- PictureBox nesnesinin bu özelliği ile istenilen x,y koordinatına bir resim yapıştırabiliriz. Her karesi 16 pixel olmak üzere yatayda 480 / 16 = 30 ve düşeyde 320 / 16 = 20 kare oluşacak. Biz istediğimiz bir koordinatı verip buraya resim yapıştıracağız. Kullanımı : PictureBox.PaintPicture Resim.Kaynağı , YatayKoord, DüşeyKoord Ekran.PaintPicture parca.picture , 16, 16 Form başlarken PictureBox nesnesinin Scale ayarını yapalım. Private Sub Form_Load() Ekran.Scale ( 1 , 1 ) - ( 31 , 21 ) ' Bu şekilde 30 x 20 şeklinde karelere ayrılmış oldu. End Sub Ekranın çevresine duvar yerleştirmemiz gerekir. Ayrıca 10 birim uzunluğunda bir yılanı ekranın ortasına Doğu yönünde gidecek bilgisiyle yerleştiririz. Rastgele bir puan koordinatı üretip puanı da yerleştiririz. Bunları yaparken aynı bilgileri Tablo dizisine de kaydedeceğimizi unutmayın. Yılanın yerleşiminden sonra başlangıç ve bitiş karelerinin değerleri ve yönü Konum dizisine kaydedilir. Dim Tablo(1 To 30, 1 To 20) As Byte Dim Konum(1 To 5) As Byte Private Sub Form_Load() Ekran.Scale (1, 1)-(31, 21) ' Tablo Temizlenir. For i = 1 To 30 For j = 1 To 20 Tablo(i, j) = 0 Next j Next i ' Yatay Duvarları Yerleştir For i = 1 To 30 Ekran.PaintPicture duvar.Picture, i, 1: Tablo(i, 1) = 1 ' Üst Yatay Sıra Ekran.PaintPicture duvar.Picture, i, 20: Tablo(i, 20) = 1 ' Alt Yatay Sıra Next ' Düşey Duvarları Yerleştir For i = 2 To 19 Ekran.PaintPicture duvar.Picture, 1, i: Tablo(1, i) = 1 ' Sol Düşey Sıra Ekran.PaintPicture duvar.Picture, 30, i: Tablo(30, i) = 1 ' Sağ Düşey Sıra Next ' Yılanı Yerleştirelim. Yılan 10 kare uzunluğunda ve yönü 2 (doğu) For i = 11 To 20 Ekran.PaintPicture parca.Picture, i, 10: Tablo(i, 10) = 2 Next 'Rasgele Bir Puan Yerleştirelim. 10: Randomize Timer x = Fix(Rnd * 30) + 1 y = Fix(Rnd * 20) + 1 If Tablo(x, y) = 0 Then Ekran.PaintPicture yem.Picture, x, y Tablo(x, y) = 8 Else GoTo 10 End If Konum(1) = 20 Konum(2) = 10 Konum(3) = 11 Konum(4) = 10 Konum(5) = 2 End Sub Projeyi çalıştırırsanız sonucu görürsünüz. Şu an hiçbir kontrol yok. Yön kontrollerini ekleyelim. Private Sub Ekran_KeyDown(KeyCode As Integer, Shift As Integer) Select Case KeyCode Case 37: If Konum(5) <> 2 Then Konum(5) = 4 ' Batı Case 38: If Konum(5) <> 3 Then Konum(5) = 5 ' Kuzey Case 39: If Konum(5) <> 4 Then Konum(5) = 2 ' Doğu Case 40: If Konum(5) <> 5 Then Konum(5) = 3 ' Güney Case 19: If Timer1.Enabled = True Then Timer1.Enabled = False Else Timer1.Enabled = True ' Pause Tuşu Case 32: Timer1.Enabled = True ' Space Tuşu End Select End Sub Ana döngüye de sorgulama ve kontrol kodlarını eklersek olay biter. Aşağıda, programın, kontrol edilmiş ve çalışan kodları bulunmaktadır. Yukarıdaki nesneleri ve ayarlamaları yaptıktan sonra bu kodları direkt olarak formun içine yapıştırın. Dim Tablo(1 To 30, 1 To 20) As Byte Dim Konum(1 To 5) As Byte Dim Puan As Boolean Private Sub Ekran_KeyDown(KeyCode As Integer, Shift As Integer) Select Case KeyCode Case 37: If Konum(5) <> 2 Then Konum(5) = 4 ' Batı Case 38: If Konum(5) <> 3 Then Konum(5) = 5 ' Kuzey Case 39: If Konum(5) <> 4 Then Konum(5) = 2 ' Doğu Case 40: If Konum(5) <> 5 Then Konum(5) = 3 ' Güney Case 19: If Timer1.Enabled = True Then Timer1.Enabled = False Else Timer1.Enabled = True ' Pause Tuşu Case 32: Timer1.Enabled = True ' Space Tuşu End Select End Sub Private Sub Form_Load() Ekran.Scale (1, 1)-(31, 21) ' Tablo Temizlenir. For i = 1 To 30 For j = 1 To 20 Tablo(i, j) = 0 Next j Next i ' Yatay Duvarları Yerleştir For i = 1 To 30 Ekran.PaintPicture duvar.Picture, i, 1: Tablo(i, 1) = 1 Ekran.PaintPicture duvar.Picture, i, 20: Tablo(i, 20) = 1 Next ' Düşey Duvarları Yerleştir For i = 2 To 19 Ekran.PaintPicture duvar.Picture, 1, i: Tablo(1, i) = 1 Ekran.PaintPicture duvar.Picture, 30, i: Tablo(30, i) = 1 Next ' Yılanı Yerleştirelim. Yılan 10 kare uzunluğunda ve yönü 2 (doğu) For i = 11 To 20 Ekran.PaintPicture parca.Picture, i, 10: Tablo(i, 10) = 2 Next 'Rasgele Bir Puan Yerleştirelim. 10: Randomize Timer x = Fix(Rnd * 30) + 1 y = Fix(Rnd * 20) + 1 If Tablo(x, y) = 0 Then Ekran.PaintPicture yem.Picture, x, y Tablo(x, y) = 8 Else GoTo 10 End If Konum(1) = 20 Konum(2) = 10 Konum(3) = 11 Konum(4) = 10 Konum(5) = 2 End Sub Private Sub Timer1_Timer() Puan = False ' Puan alınıp-alınmadığı Select Case Konum(5) Case 2: ' Doğu Yönüne If Tablo(Konum(1) + 1, Konum(2)) = 0 Or Tablo(Konum(1) + 1, Konum(2)) = 8 Then If Tablo(Konum(1) + 1, Konum(2)) = 8 Then Label1.Caption = Val(Label1.Caption) + 1 Puan = True End If Tablo(Konum(1), Konum(2)) = Konum(5) Konum(1) = Konum(1) + 1 Else ' Yılan Çarptı Timer1.Enabled = False MsgBox "Kaybettiniz" Exit Sub End If Case 3: ' Güney Yönüne If Tablo(Konum(1), Konum(2) + 1) = 0 Or Tablo(Konum(1), Konum(2) + 1) = 8 Then If Tablo(Konum(1), Konum(2) + 1) = 8 Then Label1.Caption = Val(Label1.Caption) + 1 Puan = True End If Tablo(Konum(1), Konum(2)) = Konum(5) Konum(2) = Konum(2) + 1 Else ' Yılan Çarptı Timer1.Enabled = False MsgBox "Kaybettiniz" Exit Sub End If Case 4: ' Batı Yönüne If Tablo(Konum(1) - 1, Konum(2)) = 0 Or Tablo(Konum(1) - 1, Konum(2)) = 8 Then If Tablo(Konum(1) - 1, Konum(2)) = 8 Then Label1.Caption = Val(Label1.Caption) + 1 Puan = True End If Tablo(Konum(1), Konum(2)) = Konum(5) Konum(1) = Konum(1) - 1 Else ' Yılan Çarptı Timer1.Enabled = False MsgBox "Kaybettiniz" Exit Sub End If Case 5: ' Kuzey Yönüne If Tablo(Konum(1), Konum(2) - 1) = 0 Or Tablo(Konum(1), Konum(2) - 1) = 8 Then If Tablo(Konum(1), Konum(2) - 1) = 8 Then Label1.Caption = Val(Label1.Caption) + 1 Puan = True End If Tablo(Konum(1), Konum(2)) = Konum(5) Konum(2) = Konum(2) - 1 Else ' Yılan Çarptı Timer1.Enabled = False MsgBox "Kaybettiniz" Exit Sub End If End Select Ekran.PaintPicture parca.Picture, Konum(1), Konum(2) If Puan = False Then ' son kare silinir. Ekran.PaintPicture bos.Picture, Konum(3), Konum(4) 'önceki yöne göre konum3 ve 4 ayarlanır. Select Case Tablo(Konum(3), Konum(4)) Case 2: Konum(3) = Konum(3) + 1 Tablo(Konum(3) - 1, Konum(4)) = 0 Case 3: Konum(4) = Konum(4) + 1 Tablo(Konum(3), Konum(4) - 1) = 0 Case 4: Konum(3) = Konum(3) - 1 Tablo(Konum(3) + 1, Konum(4)) = 0 Case 5: Konum(4) = Konum(4) - 1 Tablo(Konum(3), Konum(4) + 1) = 0 End Select Else ' Yeni Bir Puan Rasgele Ekrana Konur. 20: Randomize Timer x = Fix(Rnd * 30) + 1 y = Fix(Rnd * 20) + 1 If Tablo(x, y) = 0 Then Ekran.PaintPicture yem.Picture, x, y Tablo(x, y) = 8 Else GoTo 20 End If End If End Sub Bu kodlar daha da kısaltılabilir. Mesela rasgele puan yerleştirme işlemi ve yön kontrolü için bir sub veya function yapılabilir. Sub PuanKoy() BasaGel: Randomize Timer x = Fix(Rnd * 30) + 1 y = Fix(Rnd * 20) + 1 If Tablo(x, y) = 0 Then Ekran.PaintPicture yem.Picture, x, y Tablo(x, y) = 8 Else GoTo BasaGel End If End Sub Bu şekilde diğer bazı kodlar da kısaltılabilir. Niye kısaltmadım?? Uzun yoldan anlaşılması kolay olsun diye.. Dim Tablo (1 to 20, 1 to 20, 1 to 20 ) as byte Dim Konum (1 to 7) as byte Bir kenarı 20 birimlik bir küp içinde 3 boyutlu hareket edebilen bir yılan tasarlayın. Walla ben bilsem hemen yaparım. Yılanın koordinatları (11,8,17) şeklinde 3 boyutlu olacak. Konum (1-2-3) ile baş kısmını Konum (4-5-6) ile son kısmını tutacağız. Yön ise 6 farklı değer alır. (ileri-geri-sağ-sol-yukarı-aşağı) 2-3-4-5-6-7 değerlerini verin. Puan zaten 8 değerinde. Olay bitti.
__________________
bir silahım olsaydı...
![]() hiç bir farklılık ayrımcılığa neden olamaz. Hürriyet Hürriyettir. |
|
|
|
![]() |
| Seçenekler | |
| Stil | |
|
|