GML Başlangıç Kılavuzu (Çeviri Ders)(Programlama Geçmişi Gerekmez)

Yayınlandı: 21 Ağustos 2011 yasirkula tarafından Çeviri Dersler, Game Maker, Oyun Tasarımı içinde

Merhabalar, bu yazıda paylaşacağım şey bir Game Maker eğitici dosyası. Bu eğitici kılavuz sayesinde hiçbir programlama geçmişiniz olmadan GML’ye giriş yapıyorsunuz. Kılavuzda anlatılanlar ise: GML’nin temel yapısı, diziler, önemli fonksiyonlar ve pratik kodlar. Bu ders İngilizce’den çevrilmiştir, yazım hatalarının minimuma indirilmesi için de baştan sona kontrol edilmiştir.

Bu dersin orijinal İngilizce hâlini görmek istiyorsanız tıklayın: http://www.docstoc.com/docs/17279180/Super-Easy-GML-Tutorial

Ders Word’de 14 sayfa tutmuştur. Aşağıdaki download linkinden indireceğiniz Winrar arşivinin içerisinde dersin PDF, RTF (WordPad’in açtığı tür) ve henüz ilk defa kullanmış olacağım XPS (Windows 7 ile gelen, PDF’ye alternatif bir format. Vista’da olmayabilir..) formatlarındaki hâlleri vardır. Winrar arşivi 630 KB‘tır. Dersi herhangi bir yerde paylaşabilirsiniz ancak kesinlikle kendiniz yazmışsınız gibi sahiplenemezsiniz.

Dersi İndirmek İçin Link

https://www.box.com/s/fafa31e1258c47868ee4 (Alternatif link)

Ders resimsiz olduğu için dilerseniz site üzerinden de okuyabilirsiniz. Bunun için ise yazının devamını okumanız yeterli. 🙂

(öğrenmesi-kolay)Game Maker Language (GML) Eğitimi

FİNAL versiyonu

General_Leo (Pixel Perfect Games) tarafından yazılmıştır.

Süleyman Yasir KULA tarafından Türkçe’ye çevrilmiştir.


İçindekiler

Aşağıdaki parçalardan birini aramak için CTRL+F kombinasyonunu kullanıp o bölümün ismini aratın.

                                                               ANAHTAR SÖZCÜK          AÇIKLAMA

                                               BİR1                             Bu kılavuz hakkında

                                               İKİ2                              GML’nin temel yapısı

                                               ÜÇ3                              Basit Komutlar

                                               DÖRT4                         Dizilere (Array) Genel Bir Bakış

                                               BEŞ5                           Pratik kodlar

                                               ALTI6                           Sona yaklaşırken

 

—————————————————————————-

BİR1 – Bu kılavuz hakkında

—————————————————————————-

Bu eğitim dosyasının da diğer pek çok dosya gibi, Game Maker’da kod yazmanın nasıl işlediğini anlatan sıkıcı bir kılavuz olacağını düşünebilirsiniz. Şimdiden söyleyeyim, bu kılavuz Game Maker’da kod yazmayı GERÇEKTEN isteyen ancak bu uğurda özel ders almak veya diğer bazı eğitim dosyalarındaki sıkıcı ve boğucu anlatımla uğraşmak istemeyen kimseler için oluşturulmuştur.

 

Söz veriyorum ki sizi teknik terimlerle sıkmamak için elimden geleni yapacağım. Sizinle, şu an ne yaptığınızdan bihabermişsiniz gibi konuşacağım. Bu sizin olayları daha rahat kavrayabilmenizi sağlayacaktır. Başlamadan önce sizlere, eğitim dosyamı daha rahat kavrayabilmeniz için, en azından Game Maker’daki sürükle-bırak aksiyon yapısının temellerini bilmenizi ÖNEMLE tavsiye ediyorum.

 

Bu kılavuzda yer alan KALIN yazılar komutlardır ve herhangi bir şekilde değiştirilemezler, normal yazılar ise kodların değiştirilebilir kısımlarıdır. (İKİ2 ve ÜÇ3 bölümleri için konuşuyorum.)

 

========================================================================

NOT. Bu kılavuz GM6 ve üzeri sürümlerde çalışabilecek şekilde oluşturulmuştur ve GM5.3 veya aşağısında tam verimle çalışamayabilir.

========================================================================

 

—————————————————————————-

İKİ2 – GML’nin temel yapısı

—————————————————————————-

Burada en temel konularla başlayacağız. Bu temel yapının tıpkı sürükle-bırak yapısında olduğu gibi işlediğini farkedebilirsiniz. Ayrıca başlamadan söyleyeyim, büyük harf kullanmak kesinlikle SAKINCALIDIR! Tüm hazır komutlar ve fonksiyonlar daima küçük harfle başlarlar. (EKLEME: Kılavuz boyunca geçen; if‘in kelime anlamı eğer‘dir. not‘un kelime anlamı ise değil‘dir.)

 

Çevirmen Eklemesi: Bu kılavuz yazılırken Game Maker’ın kolaylaştırıcı yazılım grameri kullanılmıştı. Ancak ben Game Maker’dan sonra başka bir dile geçerken sıkıntı yaşamayın diye evrensel olarak, tüm programlama dillerinde sabit olan grameri kullanarak kodları tekrar düzenledim. (Yani örneğin if() ifadesinin (statement) içerisinde bir eşitlik sorgulanırken evrensel gramerde == işareti kullanılırken Game Maker’da bu kolaylık olsun diye = şeklinde de yazılabilmektedir ve bu kılavuzun orijinalinde de öyle kullanılıyordu. Veya bir if() ifadesinin içerisine sorgu deyimi yazılırken önce iki adet parantez kullanılır ve ilgili deyim bu parantezlerin içerisine yazılır. Bu kılavuzda ise buna dikkat edilmemiş, kodlar parantez açılmadan yazılmıştır. Ancak ben bu tip şeyleri; az önce de dediğim gibi, evrensel gramere göre düzenledim. Bir başka ÖNEMLİ örnek vermek gerekirse, evrensel gramerde, kod yazarken her satırdaki ifadenin sonuna ; (Noktalı virgül) işareti konur, ancak bu kolaylık olsun diye Game Maker’da gerekmemektedir. Tabi ben de (yine) bu soruna da el attım 🙂 )

 

Çevirmen Eklemesi2: Kılavuz boyunca yazılan kodların daha okunaklı olması için “if()” ifadelerinin içerisine yazılan kodları TAB tuşuna basarak öne çıkardım. Böylece kodlar daha düzenli ve okunaklı olurlar. Ayrıca bu evrensel programlama gramerinde de bulunan, kodlarınızda uygularken kesinlikle herhangi bir soruna sebep olmayacak bir özelliktir.

 

if(birşey)

şunu yap

Buradaki “birşey” kısmını örneğin bir değişkenle (variable) değiştirirseniz Game Maker’a belli bir şart gerçekleştiğinde bir parça kodu çalıştırmasını söyleyebilirsiniz. Şimdilik “birşey” kısmıyla ilgilenelim, daha sonra “şunu yap” kısmına bakacağız.

 

if(Timer==1)

şunu yap

Buradaki kod, “Timer” değişkeninin değeri 1’e eşit olduğu sürece gerçekleştirilecektir. Ayrıca isterseniz “==” (Eşittir) işareti yerine “<” (Küçüktür) ve “>” (Büyüktür) işaretlerini de kullanabilirsiniz. Unutmayın, “timer” ve “Timer” ismindeki değişkenler aynı şey değildirler, farklı değişkenlerdirler. Bu yüzden değişken isimlerinde küçük-büyük harflere dikkat edin. Ayrıca bir değişkeni kullanmadan önce ona en azından 0 değerini vererek o değişkeni oluşturmak (tanımlamak) zorundasınız. Bunu objenin Create (Oluşum) eventinde (olay) yapabilirsiniz.

 

if(Timer>1)

şunu yap

 

if(Timer > 1)

şunu yap

Burada kod yazarken boşlukların önemli olmadığını göstermek istedim. Üstteki kodla bu kod TAMAMEN aynı şeyi gerçekleştirirler (Dikkatli bakarsanız üstteki kodda ögeler arasında boşluk olmadığını görürsünüz.). Bu kodu nasıl yazacağınız tamamen size kalmıştır.

 

if(Timer >= 1)

şunu yap

Yapabileceğiniz başka birşey de >, = veya < işaretlerini ikişerli olarak kullanmaktır. Game Maker >= işaretini “büyüktür ya da eşittir” olarak algılar. Ne zaman = işaretini başka bir işaretle kullanırsanız, = işaretinin ikinci sıraya yazılacağını unutmayın. Ayrıca “birşey” kısmında değişken kullanmak yerine birazdan göstereceğim gibi bir komut da (command) kullanabilirsiniz. Siz bir komut yazarken Game Maker’ın, kodu yazdığınız noktanın biraz aşağısında bir kutucukta, yazdığınız komutla ilişkili tüm komutları otomatik olarak listelediğini gözlemleyebilirsiniz. Tüm bu komutlar ise yardım dosyasında (GM Kılavuzu) (F1 tuşuyla erişilebilir.) açıklanmıştır.

 

if(distance_to_object(ben) == 10)

şunu yap

Az önceki kodlara göre büyük bir sıçrayış yapıp bu koda geçmiş olabiliriz ancak hadi incelemeye başlayalım. Eğer “ben” objesine olan mesafe (distance) 10’a eşit olursa, “şunu yap” kısmı gerçekleştirilecektir (Buradaki mesafe 10 pixel’dir.). Bu komut için ayrıca > veya < işaretlerini de kullanabilirsiniz. Bu komut genelde düşman yapay zekalarında (AI) kullanılarak oyuncunun düşmandan ne kadar uzakta olduğu hesaplanır, ya da başka bir objeden. Bu kılavuzda; buna benzer birkaç komutu açıkladığım bir bölüm bulunmaktadır. Bunun için “İçindekiler” kısmına bakabilirsiniz.

 

if(distance_to_object(ben) > 50 && Timer > 1)

şunu yap

Tamam, bu kodu anlamak biraz daha zor olabilir ancak bu kodun kullanımı hâlâ oldukça kolaydır. Buradaki “&&” işaretinin anlamı “ve”dir. Yani buradaki kodun anlamı, eğer “ben” objesi kodun yazıldığı objeden 50 pixel’den daha uzaktaysa VE kodun yazıldığı objenin “Timer” değişkeni (variable) 1’den büyükse “şunu yap” kısmı çalıştırılacaktır. Unutmayın, eğer iki koşul da sağlanmazsa HİÇBİR şey yapılmayacaktır. İstediğiniz kadar koşulu, araya “&&” işareti koyarak kullanabilirsiniz.

 

if(Timer > 1 && < 10)

şunu yap

Bu kodda yanlış bir şey yok mu? Evet, bu HATALI bir koddur ve GM’de bu kodda hata verecektir. “&&” kullanırken bir komutu veya değişkeni tekrar sorgulayacaksanız o değişkeni veya komutu tekrar yazmalısınız. Bu kodu yukarıdaki gibi yazmak GM’nin şöyle düşünmesine neden olur: “eğer ne 10’dan küçükse???”

 

if (Timer > 1 && Timer < 10)

şunu yap

Bu kodda “Timer” değişkeni 2’den 9’a kadar bir değere sahipse “şunu yap” kısmı gerçekleştirilir. Bu, üstteki kodun doğru yazılmış hâlidir.

 

if (Timer >= 1 && Timer <= 10)

şunu yap

Bu kod, araya birkaç = işareti koymamın dışında, üstteki kodun aynısıdır. Sadece 1’den büyük mü ve 10’dan küçük mü diye bakmak yerine artık GM 1 ve 10 değerlerine eşit mi diye de bakacaktır. Yani bakacağı değer 1’den 10’a kadar olacaktır. Tekrar hatırlatayım, eğer = işaretini bu işaretlerden biriyle kullanacaksanız = işareti daima ikinci sırada yazılmalıdır. Ayrıca <> diye bir işaret kullanımı da vardır, bunu şimdi göreceğiz.

 

if not (Timer == 1)

şunu yap

Bu kod biraz farklı duruyor ancak <> işaretinin kullanımıyla aynı şeyi yapar. Eğer “Timer” değişkeninin değeri 1’e eşit değilse “şunu yap” kısmı gerçekleştirilir. Bunun bir başka yazılımı da “if (Timer <> 1)” şeklindedir. Bunun bir başka kullanım şekli daha vardır.

 

if (Timer != 1)

şunu yap

Bu kod üsttekiyle aynı işlemi yapar. Gördüğünüz gibi, ilgili kısma bir ! işareti koymak, “not” eklemekle TAMAMEN aynı işlevi görür. Araya ! işaretleri koyup && kullanmak kodlarınızı oldukça karmaşık gösterecektir 🙂 . Ayrıca, fonksiyonlarda (hemen hemen herşey, ama değişkenler değil) ! işareti başta olmalıdır, değişkenlerde ise gördüğünüz üzere ! işareti sonda kullanılır. Bu işareti nereye koyacağımızı bulmanın basit bir yolu ise arada = işareti olup olmadığına bakmaktır. Eğer varsa ! işareti = işaretinden hemen önce yazılır, eğer yoksa fonksiyonun kendisinin başına yazılır.

 

if(Timer ==1 || Timer == 2)

şunu yap

Bu size göstereceğim son kısayol. Kod yazarken araya || işareti koymanın anlamı şudur: Eğer Timer değişkeninin değeri 1’e eşitse VEYA 2’ye eşitse “şunu yap” kısmı gerçekleştirilir. Evet, bu; araya “or” (veya) koymakla aynı anlama gelmektedir. | işaretini yazmak içinse klavyenizden CTRL+ALT+”Shift’in sağındaki, üzerinde büyüktür ve küçüktür işaretlerinin olduğu tuş” kombinasyonuna basmanız yeterlidir. Eğer sembol kullanmak istemiyorsanız onun yerine araya “or” yazabilirsiniz.

 

Şimdi az önceki kodlara tekrar bakalım, ancak bu sefer “şunu yap” kısmını da işin içine katalım.

 

if(x ==255)

x = 100;

Bu kod, yazıldığı objenin x değerinin (yataydaki koordinatı) tam olarak 255 olup olmadığına bakar. Eğer öyleyse x değerini 100 yapar; objeniz aniden odanın solunda belirmiş olur.

 

if(Timer >= 10)

move_towards_point(10,20,30);

Bu kod Timer değişkeninin değerinin 10’a eşit veya 10’dan büyük olup olmadığını sorgular. Eğer öyleyse objeyi x=10 ve y=20 koordinatlarına doğru, 30 birimlik hızla harekete geçirir. Bu biraz karmaşık durabilir ancak unutmayın, siz “move_towards_point” fonksiyonunu yazdığınızda script editörünün alt kısmındaki çubukta ilk değerin x, ikinci değerin y, son değerin de hız (speed) için olduğu gösterilir. Peki ya birden çok işlem yapacak olursak?

 

if (Timer != 2)

{

                    move_towards_point(10,20,30);

                    Timer = 2;

}

Pekâlâ, artık yazdığımız şey bir koda benzemeye başladı, değil mi? Hadi bu kodu çözüp ne dediğine bakalım. Eğer Timer değişkeni (variable) 2’ye eşit DEĞİLSE (! işaretinin (not) “değil” anlamına geldiğini hatırlayın.), obje ilgili noktaya doğru hareket edecek VE Timer’ın değerini 2 yapacak. Eğer “if” ifadesinde yapılacak birden çok şey varsa; “if”den sonra bir { işareti ve yapılacak şeylerin sonuna da bir } işareti konur (if’den sonra ve { ile } işaretlerinden sonra ; (Noktalı virgül) işareti koymadığımıza dikkat edin! (Çevirmen Eklemesi)).Eğer && kullanırsanız bile yine bu şekilde, tek bir { } kümesi içerisine yapılacakları yazarsınız. Eğer isterseniz, içerisinde sadece 1 işlemin gerçekleştiği “if()” ifadeleri için de { } kullanabilirsiniz. (Çevirmen Eklemesi: Son cümleyi uygulamanızı tavsiye ederim. Kodlarınızın daha okunaklı olmasını sağlamanın yanı sıra başka işlere de yaramaktadırlar.)

 

if(Timer == 1 && distance_to_object(me) < 10 && x >= 10)

{

                    x = 1;

                    y = 2;

}

3 tane if koşulu kullandım, ancak yine tek bir { } kullandım. Hiçbir zaman daha fazlasına gerek yoktur, ama bir “if” ifadesinin içerisinde başka bir “if” ifadesi kullanırsanız işler değişir.

 

if(Timer == 1 || Timer == 2)

{

                    x = 300;

                    y=200;

                    if (Timer == 2)

                    {

                        Timer =3;

                    }

}

Eğer Timer değişkeni 1’e VEYA 2’ye eşitse objeyi x=300 ve y=200 koordinatlarına ışınlıyoruz ve eğer Timer’ın değeri 2 ise değerini 3 yapıyoruz. Burada iç içe 2 “if()” ifadesi kullandık ancak sonuç olarak yine her “if()” ifadesi için tek bir { } kullanımı yetti. Ayrıca kod yazarken boşlukların önemli olmadığını da tekrar göstermiş oldum. (Bakınız: “x = 300;” ve “y=200;”)

 

 

Bir kodun içerisinde illa ki “if()” ifadesi kullanmanıza gerek yoktur.

Timer += 1;

Örneğin bu kodu bir objenin Step (Adım) eventinin içerisine yerleştirirseniz o objedeki “Timer” değişkeninin değeri sürekli olarak 1 artar. Ayrıca bir değişkenin değerini artırmak için araya = işareti koymalısınız (Bir tane = işareti koyduğumuza dikkat edin. “if()” ifadelerinde, bir değeri sorgularken ise == kullanmıştık, yani 2 tane koymuştuk. (Çevirmen Eklemesi)). Bunu gidip de “Timer + 1” olarak yazamazsınız, işe yaramaz ve hata alırsınız. (Ayrıca bu ifadeyi dilerseniz Timer=Timer+1 olarak da yazabilirsiniz, tamamen aynı görevi görür. Ancak Timer+=1 kullanımı daha pratik olduğu için tavsiyem o yöntemi kullanmanızdır. (Çevirmen Eklemesi)).

 

Timer = 1;

Bu kodun yaptığı şey “Timer” değişkeninin değerini 1 yapmaktır (assign). Ayrıca isterseniz bu kodu şöyle de yazabilirsiniz.

 

if (Timer != 1)

Timer = 1;

Bu kod sayesinde, eğer “Timer” değişkeninin değeri 1’e eşit değilse onun değeri 1 yapılır. (Yazar bu kısmı yazarken başta bir “if” ifadesi kullanmanın sürekli bir değişkeni değiştirmeye göre daha performanslı olacağını söylüyor. Bu ise benim epey kafama takıldı ve üşenmedim, Game Maker’ın resmî İngilizce forumlarında direk bu konuyla ilgili yeni bir konu açtım. Bunun üzerine bir test yaptılar ve bir odaya 10.000 tane obje koyup ilk seferde objenin Step eventine sadece “Timer=1” kodunu yazdılar. Ardından 2. seferde ise bu sefer başına buradaki gibi bir “if” ifadesi eklediler. Sonuçlara göre ilk testte 3-4 fps daha az alındı, ancak bilgisayarın CPU’sundan ise çok daha az enerji harcandı. Ancalayacağınız buradaki gibi bir “if” ifadesi eklemek teoride oyunumuzu hızlandırıyor ancak çok daha fazla güç tükettiriyor bilgisayara. Ayrıca 1.000-2.000 objeye kadar olan bölümlerde bu 2 koddan hangisini yazarsanız yazın herhangi bir hız farkı göremezsiniz. Çok çok fazla sayıda obje olursa hız birazcık farkeder. (Çevirmen Eklemesi)).

 

Şimdi basitçe, kodlar vasıtasıyla başka objelerle haberleşme yöntemini görelim.

 

x =Karakter.x;

Eğer mevcut odada “Karakter” adında bir obje varsa, bu kod sayesinde kodu hangi objeye yazdıysanız; o obje yatay eksende “Karakter” objesinin bulunduğu x koordinatına ışınlanır. Burada anlaşılmayacak bir şey yok heralde?!

 

x =Karakter.x;

y =Karakter.y;

Bu kod x ve y koordinatlarını sürekli “Karakter” objesininkiyle aynı tutarak, kodun yazıldığı objeyi “Karakter” objesine yapışık yapar. Bu kod eğer step eventine yerleştirilirse normal şartlarda her saniyede 30 kere gerçekleştilir, ancak zaman zaman “Karakter” objesi hareket ettiğinde kodu yazdığımız objemiz tam olarak “Karakter”e yapışık hareket etmeyebilir, onun biraz gerisinden gelebilir. Bu yüzden burada objeler yerine spriteler kullanmak daha mantıklıdır.

 

x += 1;

Bu kodu pek çok oyunda kullanabilirsiniz. Eğer bu kodu “keyboard right” (sağ ok tuşu) eventine koyarsanız, klavyeden sağ ok tuşuna bastığınızda objeniz sağ yöne doğru pixel pixel hareket eder. “+” işareti yerine “-” işareti koyarsak da sola doğru hareket eder.

 

 

 

Artık kod yazmanın temel parçalarını biliyorsunuz. Şimdi yapmanız gereken, eskiden sürükle&bırak (Drag&Drop) yaparak kullandığınız aksiyonları, kodlar vasıtasıyla kullanmak. Bunun için size Game Maker Manual’a bakmanızı tavsiye ediyorum. (F1 tuşuyla bakabilirsiniz, İngilizce’dir.) Buradan arama yoluyla ya da rasgele olarak çeşitli kodlara bakıp inceleyin. Şimdi sizinle önemli birkaç kodu paylaşayım…

 

—————————————————————————-

ÜÇ3 – BasitKomutlar

—————————————————————————-

Burada vereceklerim en yaygın olarak kullanılan fonksiyonlar, komutlardır. LÜTFEN GM manual’e bakarak tüm bu kodlara ayrıntılı olarak bir de oradan bakın. Ayrıca bir komutta büyük harf KULLANILAMAYACAĞINI da sakın unutmayın.

 

OBJE AYARLARI

——————

1. image_alpha

 

Bu kod bir objenin ne kadar görünür ya da saydam (transparent) olduğunu belirler. Değerini 0 yaparsanız obje tamamen görünmez olur, 1 yaparsanız tamamen görünür olur. Saydam bir obje için genelde 0.4 değeri uygundur.

 

2. image_index

 

Bu, animasyonlu bir spritede, animasyonun başka bir karesine geçiş yapmanızı sağlar. Animasyonlu spritelerin başlangıç kareleri (frame) 0’dır. Yani 4 kareden oluşan bir animasyonlu spritenin kareleri 0’dan 3’e kadar numaralandırılır. Bu komutu kullandıktan sonra, animasyonun oynatılmasını istemiyorsanız bir de image_speed’i (resim_hızı) 0’a ayarlamalısınız.

 

3. image_speed

 

Bir objenin image_speed’ini değiştirmek, o objenin spritesi eğer animasyonluysa, o animasyonun ne kadar hızlı olarak gösterileceğini belirler. Çoğunlukla bir objeyi odaya ilk koyduğunuzda spritesindeki animasyon oldukça hızlı olur ve bunu biraz yavaşlatmak gerekir. Bunun için o objenin Create (Oluşum) eventinde “image_speed=0.5;” kodunu eklemek, spritedeki animasyonun yarı hızda gösterilmesini sağlar ve bize oldukça yardımcı olur. Değerini 0 yaparsak animasyon oynamaz, o anki animasyon karesi gösterilmeye devam eder.

 

4. sprite_index

 

Bu komutla bir objenin spritesini değiştirebilirsiniz. Örneğin bir platform oyununda karakterin zıplarken farklı bir sprite gösterilmesini sağlamak isteyebilirsiniz. Bunun için zıplama butonunun eventine bu komutu yazıp değerini, ilgili zıplama spritesinin İSMİNE eşitleyin. (Örneğin: “sprite_index = karakter_ziplama;” gibi.

 

5. solid

 

Objenizi solid yapıp yapmamaya yarayan komuttur. Değerini “true” veya “false” yapmalısınız. “true” yaparsanız objeniz solid (eylemsiz obje, sabit katı) olacaktır.

 

6. visible

 

Objenizin görünürlüğünü ayarlamaya yarar. Değerini “true” yaparsanız objeniz sahnede görünür, “false” yaparsanız görünmez olur.

 

7. persistent

 

Bu komutla bir objeyi persistent (odalar arası kalıcı, başka bir odaya geçerken kaybolmadan, aynı özelliklerle geçiş yapan objelere denir.) yapabilirsiniz. Değerini “true” yaparsanız objeniz persistent olur ve başka odalara geçince aynen o odaya da aktarılır.

 

8. speed

 

Bir objenin speed (hız) değişkenini ayarlayarak onun ne kadar hızlı hareket edeceğini belirleyebilirsiniz. Bu image_speed’i değiştirmekle aynı şey DEĞİLDİR. speed değişkeni, obje herhangi bir yönde harekete geçince, objenin hızını ifade eder.

 

9. x

 

Bir objenin x değişkenidir, yani yatay eksendeki koordinatıdır. Bu komutla bir objeyi sağa sola hareket ettirebilirsiniz. (“x+=3”, “x-=7” gibi…)

 

10. y

 

Bir objenin y değişkeni, yani dikey eksendeki koordinatıdır.

 

11. hspeed

 

hspeed‘i (yatayhiz) değiştirmek x değişkeninin değerini değiştirmek gibidir, ancak hspeed değişkenini değiştirmek, objeye bir hareketlilik kazandırmak için daha iyidir. “hspeed+=1;” yazarsanız objenizin yataydaki hızı sürekli olarak, yavaş bir şekilde artacaktır. Bu koddan önce bir “if()” ifadesi kullanılarak maksimum alınabilecek hız değeri belirlenebilir.

 

12. vspeed

 

vspeed (dikeyhiz) değişkenini değiştirmek y değişkenini değiştirmeye benzer. “vspeed+=1;” yazarsanız objeniz aşağı yönde, düzenli olarak hızlanarak ilerlemeye başlar. Başında bir “if()” ifadesi kullanılarak hız limitlenebilir. vspeed değişkeni özellikle yerçekimi yapmak için vazgeçilmez bir değişkendir.

 

13. gravity

 

Ne zaman ki yerçekimi 0’dan büyüktür, o zaman aşağı doğru bir kuvvetin etkisi altında kalırsınız. Bir objenin solid bir zeminde durmasını sağlamak için gravity (yerçekimi) değişkeninin değerini tekrar 0 yapmalısınız. gravity değişkenini zıplamak için kullanabilirsiniz ancak bunun yerine vspeed değişkeninin kullanımı daha rahat olacaktır.

 

14. image_angle

 

Bu özelliği kullanabilmek için tam sürüm Game Maker’ınız olmalıdır. Bu kod oldukça kullanışlıdır, objenin belli bir açıyla durmasını sağlar. Mesela “image_angle=point_direction(x,y,mouse_x,mouse_y);” yazılı bir kodu step eventine koyarsanız objeniz otomatik olarak, sürekli mouseye doğru bakacaktır. Bu değişken 0 ile 360 arasında bir değer alabilir ve 0 değerinde sağ yön kastedilir. Yani bir objenin mouseye bakmasını istiyorsanız, orijinal spritenizdeki karakteriniz sağ yöne bakıyor olmalıdır. Ne yazık ki bu komutu kullanınca genelde spritenin grafik kalitesi düşer, bu yüzden bu komut her zaman en iyi çözüm değildir.

 

Oyun Esnasında Birşeyleri Değiştirmek (Fonksiyonlar)

——————

1. instance_create(x,y,bir_obje)

 

Bu kod ÇOK SIK kullanılır, yaptığı şeyse odada, bir objenin yeni bir instance’sini (kopya) oluşturmaktır. Fonksiyonun içine, kopyanın oluşturulacağı x ve y koordinatları ile objenin adı girilir.

 

2. distance_to_object(bir_obje)

 

Bu fonksiyon sayesinde, “bir_obje” isimli objenin, kodun yazıldığı objenin kopyasına ne kadar pixel uzaklıkta olduğunu bulabilirsiniz. Bu; “if(distance_to_object(objemiz) < 100)” gibi bir sınama ifadesinde bol bol kullanılır. Bu sayede bir objenin örneğin karakterinize olan mesafesine bakarak pek çok şeyi değiştirebilirsiniz.

 

3. distance_to_point(bir_obje.x,bir_obje.y)

 

distance_to_object fonksiyonuyla aynı temel üzerine kuruludur. Ancak bu sefer mesafe için bir obje ismi girmek yerine, harita üzerindeki bir noktanın x ve y koordinatlarını gireriz.

 

4. move_towards_point(x,y,hiz)

 

Kodun yazıldığı objeyi, x ve y koordinatları girilen noktaya doğru, “hiz” hızında hareket ettirmeye yarar. “hiz” değerini 10 ya da 15 gibi, bir sayı girmelisiniz.

 

5. keyboard_check(vk_left)

 

Bu fonksiyon sayesinde, bir klavye tuşunun basılı tutulup tutulmadığına bakabilirsiniz. Buradaki “left” (sol) kısmını istediğiniz ok tuşuna göre değiştirebilirsiniz: “right” (sağ), “up” (yukarı), “down” (aşağı), “alt”, “backspace”, “control”, “anykey” (Herhangi bir tuş”, “nokey” (Hiçbir tuş)… Ayrıca bu fonksiyonu keyboard_check_pressed() veya keyboard_check_released() olarak da değiştirebilirsiniz. Bunu yaparsanız, fonksiyonun klavye tuşuna basılı tutulduğu sürece gerçekleşmesi yerine, sadece ilk basıldığında gerçekleşmesini veya tuştan elimizi çekince gerçekleşmesini sağlayabilirsiniz.

 

6. instance_place(x,y,bir_obje)

 

Bu fonksiyon, “bir_obje” objesinin, girilen koordinatlarda herhangi bir kopyasının bulunup bulunmadığını kontrol eder. Çok sık kullanılır.

 

7. sleep(ms)

 

Bu fonksiyon, GM’yi belirli bir süre, tamamen duraklatmaya (pause) yarar. “ms” yerine kaç milisaniyelik duraklama istiyorsanız o değeri sayı olarak girersiniz. Bu komutla GM’yi pause ettiğinizde herşey durur, bildiğime göre durmayan tek olay müzikler.

 

8. sound_play(bir_ses)

 

Bir sesi ya da arkaplan müziğini oynatmanıza yarar. Bu koddan sonra “sound_loop(bir_ses)” fonksiyonuyla, az önce çalınmasını sağladığınız sesin, oda tamamlanana kadar sürekli kendini tekrar etmesini (loop) sağlayabilirsiniz. Bu durumda ses dosyasının çalınması sadece “sound_stop(bir_ses)” fonksiyonu yazılarak durdurulabilir. Bu fonksiyonla çaldıracağınız ses dosyası GM içerisinde bir “Sound” resource’si olarak oluşturulmuş olmalıdır.

 

9. random()

 

Rasgele bir değer oluşturmak, pek çok kişinin tam olarak kavrayamadığı birşeydir. random(3) fonksiyonu, 0 ile 3 arasında olan ve kesirli sayılar da dâhil (2.3 , 1.1 vb.) RASGELE bir sayı üretmeyi sağlar. Eğer bir tamsayı döndürmek isterseniz “round(random(3))” fonksiyonunu kullanabilirsiniz. Bu sayede eğer kesirli bir sayı bulunursa, sayı kendisine en yakın olan tamsayıya döndürülecektir. Eğer ki “round()” yerine “ceil()” kullanırsanız, bulduğunuz kesirli sayı 1.1 bile olsa, o sayı bir üstündeki tamsayıya yuvarlanır, yani 2’ye. Veya “floor()” kullanarak kesirli sayının 2.7 gibi bir değer olsa bile 2’ye yuvarlanmasını sağlayabilirsiniz.

 

10. instance_nearest(x,y,bir_obje)

 

Bu fonksiyon sayesinde, kodun yazıldığı objeye en yakın mesafedeki “bir_obje” instance’si bulunur, eğer “bir_obje” instance’sinden odada yoksa hata alınır. Bu komut sayesinde örneğin bir aksiyon oyununda, yardımcılarınızın otomatik olarak en yakınlarındaki düşmana yönelmelerini sağlayabilirsiniz.

 

 

—————————————————————————-

DÖRT4 – Dizilere (Array) Genel Bir Bakış

—————————————————————————-

 

Şimdi sizlerle dizilere basitçe giriş yapacağız. Hepinizin global (evrensel) bir değişkenin ne olduğunu bildiğini varsayıyorum. (Herhangi bir objeden erişilebilen ve sadece 1 tane olan, yani objeden objeye değeri değişmeyen değişkenler.) Dizilerin hepsi 0’dan başlarlar ancak ben 1’den başlayacağım, çünkü böylesi daha normal geliyor bana.

Yeni bir dizi oluşturduğunuzda, dizinin ilk değeri “diziismi[0,0]” vb. şeklinde olmalıdır.

 

diziismi[#]

 

Bu bir dizinin temelidir. Tıpkı bir değişkende olduğu gibi, dizilere de birer isim verilir ve içerilerine bir değer atanır.

 

Esya[1]

 

Pekâlâ, bu durumda şöyle düşünebilirsiniz, bu dizinin değeri 1’dir. Ancak bu yanlış bir bilgidir, bu dizinin değeri 1 DEĞİLDİR, buradaki 1, dizide depolanan bir bilgiye erişmek için kullandığımız sıra numarasıdır. Artık bu diziye bir değer atamaya hazırız, çoğunlukla bir diziye sayı değeri atanır ancak bu sefer bir değişiklik yapıp bir yazı (String) değeri atayalım.

 

Esya[1]=”Bu eşya ile sağlığınızı tazeleyebilirsiniz.;

 

Artık 3 ana parçayı da tamamladığımıza göre dizimiz kullanıma hazır durumda. Dizimizi, tıpkı bir değişken kullanır gibi kullanabiliriz.

 

draw_text(x,y,Esya[1]);

 

Şimdi böyle bir fonksiyon kullandığımızda, odanın en sol üstünde “Bu eşya ile sağlığınızı tazeleyebilirsiniz.” yazacak. Anladınız mı? Bu dizinin yapısı tıpkı bir değişkendeki gibiydi. Şimdi biraz daha detaya inelim.

 

Esya[1]=”İksir;

Esya[2]=”Mana İksiri;

Esya[3]=”Para;

 

Şimdi bu diziyi bir envanter listesi yapmak için kullanabiliriz, bu tamamen isteğimize bağlı. Bu dizi değerlerine farklı farklı sıra numaraları vererek her birini ayrı ayrı, tek bir çatı altında depolamış oluyoruz. Artık temel mantığı kavradığınızı düşünüyor ve biraz daha derinlere dalıyorum.

 

Esya[1,0]

Esya[1,1]

 

Şimdi bu koda bakıp da “bu herif naptığını sanıyo?” diye söylenebilirsiniz. Bu kısım, dizilerin oldukça kullanışlı olduğu kısımdır (ve biraz da karmaşık olduğu.). Tamamen isteğe bağlı olarak, dizinize 2. bir sıra numarası katmanı daha ekleyebilirsiniz. Bunun kullanımını direk bir örnek üzerinde görelim, diyelim ki oyununuz için iksir yapısını kodluyorsunuz.

 

Esya[1,0]=”İksir;

Esya[1,1]=”50 can puanı tazeler.;

Esya[1,2]=1;

Esya[1,3]=100;

 

Esya[2,0]=”Elma;

Esya[2,1]=”75 can puanı tazeler.;

Esya[2,2]=3;

Esya[2,3]=200;

 

Pekâlâ, öncelikle iksirlerin özelliklerini parçalara ayırdım. 0 numarasını iksirin ismi, 1 numarasını iksirin kısaca açıklamasını, 2 numarasını iksirin elimizde bulunan miktarını, 3 numarasını da iksirin satış fiyatını depolamak için, sıra numarası olarak kullandım. Şimdi eğer isterseniz tüm bu özellikleri istediğiniz şekilde kullanabilir, yazdırabilirsiniz. Dizimizin ilk sıra numarası katmanında 1 numara olarak iksir’i tanımladıktan sonra aynı değer üzerinde birden çok şey yazamayacağımız için 1 numarasını değiştirip elma için sıra numarasını 2 yaptık. Eğer hâlâ tam olarak anlayamadıysanız bir başka örnek göstereyim. GM’yi açın ve bir objenin oluşum (Create) eventinde aşağıdaki kodu çalıştırın. Böylece daha sonradan bu dizi değerlerine erişim sağlayabileceğiz.

 

Esya[1,0]=”İksir;

Esya[1,1]=”50 can puanı tazeler.;

Esya[1,2]=2;

Esya[1,3]=100;

 

Esya[2,0]=”Mana İksiri;

Esya[2,1]=”30 mana gücü tazeler.;

Esya[2,2]=3;

Esya[2,3]=125;

 

Esya[3,0]=”Para;

Esya[3,1]=”Adanızın parasal değeri;

Esya[3,2]=12000;

Esya[3,3]=100;

 

Esya[4,0]=”Yeniden canlandırmak;

Esya[4,1]=”Ölmüş bir takım arkadaşınızı diriltmeye yarar.;

Esya[4,2]=1;

Esya[4,3]=1000;

 

Şimdi anladınız mı? Bu yapıyı sonsuza dek sürdürebilirsiniz. Ayrıca dizilerin sadece bir şeylerin değerlerini ekrana yazdırmak için kullanılmadığını da bilmiş olun. Dizilerde tıpkı bir değişken gibi, dilediğimizce kullanılabilirler. Son olarak, dilerseniz dizileri de global (evrensel) yapabilirsiniz.

 

global.Esya[4,2]=1;

 

kodu bu dizi değerine herhangi bir yerden erişim sağlayabilmenizi ve değerlerinin de odadan odaya kalıcı olmasını sağlar.

 

Eğer ki dizileri gerçek anlamda kullanmayı öğrenmek istiyorsanız şu örneğe bir göz atın…

 

draw_text(x,y, global.Esya[Numara,0]);

Bir değişken olan “Numarayı dizinin ilk sıra katmanı olarak kullanmak, “Numara” değişkeninin değerini değiştirerek ekrana yazdırılan dizi değerinin değiştirilmesini sağlar. Bu değeri 1 yaparsak (üstteki örneği baz alırsak)ekrana “İksir” yazısı yazdırılır ve eğer “Numara” değişkeninin değerini 2 yaparsa ekrana “Mana İksiri” yazısı yazdırılır. Bu yapı, size envanter, dükkan, karakter gelişimi vb. yapılarının kodlanmasında MÜTHİŞ derecede yardımcı olur.

 

—————————————————————————-

BEŞ5 – Pratik kodlar

—————————————————————————-

1. Alarm eventi kullanmadan, aynı görevi yapan bir yapı kodlamak

 

zamanlayici+=1;

if(zamanlayici>50)

{

                    bunu yap;

                    şunu yap;

                    onu yap;

                    zamanlayici=0;

}

 

Bu kodu kullanmak, alarm eventi kullanmaya göre daha pratiktir (Bence alarm eventi kullanmaya devam, bu o kadar da pratik değil; ancak yine de güzel bir kod. (Çevirmen Eklemesi.)). Sadece bu kodu step (adım) eventine yazdığınıza emin olun. Ayrıca bu yapı kodun içerisinde olduğu için objenizin yapısında daha az karmaşaya sebep olur.Ayrıca isterseniz “zamanlayici+=1;” kısmından önce başka bir “if()” ifadesi ekleyerek, zamanlayıcınızla işiniz bittikten sonra tekrar çalışmasını önleyebilirsiniz. (Bu kodu kullanırsanız Create eventine “zamanlayici=0;” kodunu eklemeyi unutmayın. (Çevirmen Eklemesi.))

 

2. Ekranın otomatik olarak konumlandırılması

 

view_hborder=view_wview/2 –karakter.sprite_width;

view_vborder=view_hview/2 –karakter.sprite_height;

 

Bu, büyük olasılıkla bildiğim en iyi “pratik kodlar”dan birisi. Sürekli view’i (ekran) resetleyerek “karakter” objesinin daima kusursuz bir şekilde ekranın ortasında durmasını sağlar. Eğer karakter objenizin spritesinin ya da şeklinin sürekli değiştiği bir oyununuz varsa, tek yapmanız gereken spritenin değiştirilmesi aksiyonundan sonra bu kodu eklemektir. Böylece her zaman karakteriniz mükemmel bir şekilde ortalanır. Ancak bunu kullanmadan önce view yapısının etkin (açık) olduğundan emin olun.

 

3. Mükemmel iniş (platform oyunları için)

 

if(vspeed > 0 && !place_free(x,y+vspeed))

{

    move_contact(270);

    vspeed = 0;

}

 

Bir platform oyunu yaparken, karakterinizin zıpladıktan sonra yere inerken yerin hemen üstünde durduğunu ve ardından aradaki birkaç pixellik boşluğu indiğini görürsünüz. Bu, çoğunlukla oyunlarınız için gayet kötü bir görünüm sunar. Onun yerine, karakterinizle yerin temas (collision) eventine buradaki kodu ekleyin. Bu komut Game Maker’ın, arada kalan birkaç pixellik boşluğa karakteri tam uygun olarak oturtmasını sağlar. Böylece inişleriniz oldukça yakışıklı ve yumuşak olacaktır.

 

4. Basitçe yerçekimi eklemek (platform oyunları için)

 

if(!instance_place(x,y+1,solid_obje))

gravity=0.5;

 

if(instance_place(x,y+1,solid_obje))

gravity=0;

 

if(vspeed>10)

vspeed=10;

 

Bu kod oldukça faydalıdır çünkü yerçekimini sadece karakterin altında sert ve katı (solid) bir obje olmadığı zaman uygular. Ayrıca dikey hızınıza bir limit koyarak yere düşüş esnasında yaşanabilen bugları bir miktar giderir. Limit değerini azaltmak daha da yardımcı olabilir ancak gerçekçiliği de azaltabilir. Çeşitli limit hızlar kullanmayı deneyebilirsiniz. “solid_obje” objesini ise yer objesi için kullandığınız obje olarak değiştirin. Eğer birden çok yer objeniz varsa, bu yer objelerini kapsayan bir parent obje (ebeveyn obje) kullanabilirsiniz.

 

5. Objeyi başka bir obje etrafında döndürmek

 

donme+=10;

x=karakter.x+lengthdir_x(karakter.sprite_width*1,donme);

y=karakter.y+lengthdir_y(karakter.sprite_height*1,donme);

 

Bu ufak kod parçası sayesinde bir objenin başka bir obje etrafında otomatik olarak çemberler çizerek dönmesini sağlayabilirsiniz. Etrafında dönülecek olan objenin ismini “karakter” kısmına yazmalısınız. Bu kod, ilgili objenin spritesinin ne kadar büyük olduğunu bulup nasıl bir çember etrafında dönmesi gerektiğini belirler. Ayrıca çember çizecek olan obje, etrafında döneceği objenin olduğu yere otomatik olarak ışınlanacağından dolayı başlangıç konumunun bir önemi yoktur. “donme” değişkeninin artma değerini değiştirerek dönme hızını değiştirebilirsiniz. Objenizin sürekli çember çizerek dönmesi için bu kodu step eventine yazdığınıza emin olun!

(Bu kod en beğendiğim pratik kodlardan birisi oldu, gerçekten çok iyi işliyor. Ancak kodu kullandığınız objelerin spritelerindeki origin noktalarının, spritenin tam merkezine ayarlandığına emin olun, yoksa objeniz diğer objenin tam olarak etrafında dönmez ve bir miktar içerisinden geçer. Ayrıca; eğer bu kodu kullanacaksanız Create eventine “donme=0;” kodunu eklemeyi unutmayın. (Çevirmen Eklemesi.))

 

6. 360 derece dönmek

 

yon = point_direction(x,y,mouse_x,mouse_y);

image_single=yon/10;

 

Bu da çok sık kullanılmaktadır. Yaptığı şeyse bir objenin sürekli olarak mouse’nin olduğu yöne doğru bakmasıdır. Bunun için “image_angle” kullanılabilirdi ancak “image_angle” sadece PRO sürümde kullanılabilen bir komuttur. Bu kodu çalıştırmak için, kodun yazıldığı objenin spritesi birden çok kareden (frame) oluşmalıdır. Tavsiyem, ilk karesi sağa doğru bakan ve 36 kareden oluşan bir sprite oluşturmanızdır. Böyle bir durumda her bir kare, kendisinden önceki kareden 10 derece daha sola yatık olmalıdır. Yani sprite, 36 karede, saat yönünün tersinde tam bir tur atmalıdır. Ardından bu kodu ilgili objenin Step eventine yazarsanız objeniz sürekli mouseye bakacaktır. Birinci satırdaki koordinatlar değiştirilerek objenin başka bir noktaya bakmasını sağlayabilirsiniz.

 

7. Bir spritedeki fontu kullanmak

 

Create eventi:

 

global.OzelFont=font_add_sprite(s_FontSprites,ord(‘ ‘),false,0);

 

Draw eventi:

 

draw_set_font(global.OzelFont);

draw_set_color(c_white);

 

 

Böyle bir işlemin nasıl yapılacağını soran pek çok insan gördüm. Buradaki kod, bir spritedeki fontu yazı yazarken font olarak kullanmayı sağlar. “OzelFont” ismini dilediğinizce değiştirebilirsiniz ve “draw_set_color()”dan, yazının rengini dilediğinizce değiştirebilirsiniz (Bu hâliyle kalırsa fontta orijinal renk kullanılır.). Game Maker’ın böyle bir işlemi yapmak için kullandığı spritenin yapısını çözmek biraz zamanımı aldı, bu yüzden de size örnek bir font spritesini aşağıda veriyorum. Buradakilerin haricinde, bulamadığım başka semboller de olabilir ancak genel anlamda kullanılan pek çok sembol bu spritede mevcut.

 

(Çevirmen Eklemesi): Burada normalde bir font spritesi olması gerekli iken ne yazık ki görselin heralde tam yüklenememesinden dolayı sprite bulunmamaktadır. Bu, orijinal İngilizce eğitim dosyasında da böyledir.

 

8. Sağlık barı

 

//DRAW eventi:

draw_set_color(c_red);

draw_line(x,y-10,x+canbari_uzunluk,y-10);

if(can_miktari > maksimum_can)

can_miktari = maksimum_can;

if(can_miktari < 0)

can_miktari = 0;

 

//STEP eventi:

canbari_uzunluk = can_miktari / maksimum_can * sprite_width;

 

Bana şimdiye kadar, nasıl bir can barı yapılacağıyla ilgili pek çok soru geldi ve bu soruları soranların genelde istedikleri şey de, can miktarının ne kadar büyük olursa olsun can barının aynı uzunlukta olmasıydı (anlayacağınız yüksek cana sahip bir karakterin can barı daha yavaş azalacak.). Bu kodun yaptığı şey de tam olarak bu. Bu kod, can barı olarak bir dikdörtgen kullanmak yerine daha basit olması için düz bir çizgi kullanmaktadır. Kodu yazdıktan sonra “maksimum_can” ve “can_miktari” değişkenlerinin değerlerini belirleyip, Create eventine “canbari_uzunluk=0;” kodunu ekleyin. Ayrıca ilk kod parçasını Draw (Çizdir) eventine, ikinci parçayı ise Step eventine koymayı unutmayın. Yukarıdaki “y-10” kısmındaki 10 değerini değiştirerek can çizgisinin daha yukarıda ya da aşağıda gözükmesini sağlayabilirsiniz (Bu değeri artırırsanız çubuk da o kadar yükselir.). Artık can barı için çizgi uzunluğu derdi olmadan herhangi bir obje için can kullanabilirsiniz. 🙂

 

9. Odanın döndürülmesi

 

view_angle[0]=-direction+90;

image_angle=direction;

 

Bu kod göründüğünden daha karmaşıktır. Tüm bir odayı, yukarıdaki kodda yazdığınız miktara göre, karakteri baz alarak döndürür (Bu kodu Step eventine yazmalısınız.). Genelde bu kodu karakter objeniz için kullanmak istersiniz. Bu kodla oyununuza gerçekten güzel bir görünüm kazandırabilirsiniz ancak bunun için PRO sürüm Game Maker sahibi olmalısınız. (Bu kodu kullanmadan önce view’in etkin olduğundan emin olun! (Çevirmen Eklemesi.))

 

—————————————————————————-

ALTI6 – Sona yaklaşırken

—————————————————————————-

 

Son olarak, bu eğitim dosyasını okuduğunuz için teşekkür ederim. Umarım bu kılavuz GML kullanımına başlamanızda yardımcı olur. Kodlama yaparken Game Maker’ın F1 tuşuyla açılan kullanma kılavuzuna düzenli olarak bakmanızı tavsiye ederim. Çeşitli kodları harmanlayarak değişik şeyler oluşturmayı deneyin.Bu işi kapmanın tek gerçek yolu bol bol pratik yapmaktır.

 

Herhangi bir sorununuz mu var?

Bana email atarak ya da AIM yoluyla ulaşabilir ve sorularınızı sorup yorumlarınızı yapabilirsiniz.

 

PM:             General_Leo ( http://forums.gamemaker.nl/index.php?showuser=3133 )

Sitem:         http://NewPPG.com (yaptığım tüm oyunlarım ve eğitici derslerim bulunmaktadır.)

Forumum:   http://NewPPG.com/Forum

Email:         OutlawCecil@gmail.com

AIM:            OutlawedUser

MSN:           OutlawCecil@gmail.com

 

Çevirmen:      Süleyman Yasir KULA

Site:             https://yasirkula.wordpress.com/

Email:          yasirkula@yahoo.com

Bana çok basit sorular sormanızın bir sakıncası yok, ancak lütfen sizin için tüm oyununuzu yapmamı istemeyin.Eğer isterseniz size yardımcı olabilirim ancak kodlamayı öğrenmenin en iyi yolu, hemen e-mail atıp nerede hata yaptığınızı sormak yerine önce bir denemektir.

Yorumlar kapalı.