Merhaba değerli e-bergi okuyucuları. Bu ay sizlere Python programlama dilinin pygame oyun kütüphanesi ile nasıl oyun yazılır ondan bahsedeceğim. Bu yazımızda anlatılanları anlamak için python programlama dili hakkında biraz bilgi sahibi olmanız gerekmektedir. Bu nedenle eğer hiç bilmiyorsanız öncelikle www.istihza.com adresindeki python derslerine göz atmanızı öneririm. Anlatırken kendi işletim sisteminizde python uygulamalarının nasıl çalıştırıldığını ve python dilini bildiğinizi varsayacağım. Eğer bilgisayarınızda python interpreter’ı yüklü değilse www.python.org/download adresinden işletim sisteminize uygun olan python yorumlayıcısını indirip kurmalısınız. Karışıklık olmaması için de benim kullandığım python sürümünün 3.1 olduğunu belirteyim. Python 3.1 de bilgisayarınızda kuruluysa artık http://www.pygame.org/download.shtml adresinden pygame’i indirip kurabilirsiniz. Burada da ben pygame 1.9 sürümünü kullanıyorum.
Bu ay pygame ile “Merhaba Dünya” programını yazalım ve gelecek ayki yazımızda basit bir oyun geliştirelim. Anlatması kolay olsun diye her satırın başında satır numarası yazılı fakat bu numaraları kendi kodunuz içine eklerseniz interpreter’dan hata alırsınız; bu yüzden denemeden önce satır numaralarını silmelisiniz.
1.import pygame, sys
2.from pygame.locals import *
3.
4\. # pygame başlıyor
5\. pygame.init()
6.
7\. # pencere oluşturuluyor
8\. pencereYuzey = pygame.display.set_mode((500, 400), 0, 32)
9\. pygame.display.set_caption('Merhaba Dünya!')
10.
11\. # renkleri belirliyoruz
12\. SIYAH = (0, 0, 0)
13\. BEYAZ = (255, 255, 255)
14\. MAVI = (0, 0, 255)
15\. KIRMIZI = (255, 0, 0)
16.
17.
18\. # yazı karakteri
19\. yaziKarakter = pygame.font.SysFont(None, 48)
20.
21\. # yazıyı oluştur
22\. yazi = yaziKarakter.render('Merhaba Dünya!', True, BEYAZ, KIRMIZI)
23\. yaziRect = yazi.get_rect()
24\. yaziRect.centerx = pencereYuzey.get_rect().centerx
25\. yaziRect.centery = pencereYuzey.get_rect().centery
26.
27\. # pencere yüzeyine beyaz arkaplan ekliyoruz
28\. pencereYuzey.fill(BEYAZ)
29
30\. # siyah çigi çiziyoruz
31\. pygame.draw.line(pencereYuzey, SIYAH, (90, 90), (150, 90), 5)
32.
33\. # mavi daire çiziyoruz
34\. pygame.draw.circle(pencereYuzey, MAVI, (400, 70), 30, 0)
35
36\. # yazıyı pencere yüzeyinde oluşturuyoruz
37\. pencereYuzey.blit(yazi, yaziRect)
38.
39\. # pencereyi ekranda oluşturuyoruz
40\. pygame.display.update()
41.
42\. # oyun döngüsünü çalıştırıyoruz
43\. while True:
44\. for olay in pygame.event.get():
45\. if olay.type == QUIT:
46\. pygame.quit()
47\. sys.exit()
Şimdi de satır satır ne yaptığımızı inceleyelim.
Başlangıç
1.import pygame, sys
2.from pygame.locals import *
İlk olarak pygame modülünü eklememiz gerekiyor çünkü pygame fonksiyonlarını kullanmak istiyoruz. Aynı şekilde sys de ekleniyor ilk satırda. 2. satırda ise pygame.locals modülünü ekliyoruz fakat “import pygame.locals” yazmak yerine “from pygame.locals import *” diyoruz. Bunun nedeni pygame.locals modülünün içindeki fonksiyonları her kullandığımızda başına pygame.locals yazmak istemememiz. Mesela sys modülünün içinde bulunan exit() fonksiyonunu en son satırda sys.exit() şeklinde kullandık çünkü sys modülünü “from sys import *” yazarak eklememiştik. Burada ne şekilde ekleyeceğimiz bize kalmış ama fonksiyonu çağırırken hangi modüle ait olduğunu bilmek bizim için daha iyi olacaktır.
4\. # pygame başlıyor
5\. pygame.init()
5. satırda kullandığımız pygame.init() ise pygame’de kullanacağımız fonksiyonların çalışması için pygame kütüphanesini başlatıyor.
pygame.display.set_mode() ve pygame.display.set_caption fonksiyonları
7\. # pencere oluşturuluyor
8\. pencereYuzey = pygame.display.set_mode((500, 400), 0, 32)
9\. pygame.display.set_caption('Merhaba Dünya!')
8. satırda pygame.display modülünün içindeki set_mode metodunu çağırıyoruz ve pencereYuzey adlı değişkene atıyoruz. set_mode metodu üç parametre alıyor. İlki (500, 400) olarak belirttiğimiz en-boy piksel miktarı. Yani 500 piksel genişliğinde ve 400 piksel yüksekliğinde bir penceremiz oluşturuldu. Diğer iki parametre ise renk derinliği gibi gelişmiş grafik arayüzü ayarları olduğu için burada değinmeyeceğiz; ikinciyi 0, üçüncüyü de 32 olarak girmeniz yeterli olacaktır. 9. Satırdaki metod ise pencerenin sol üst köşesinde çıkan başlığın yazılmasını sağlıyor. Html’deki <title>Merhaba Dünya</title> koduna benzediğini düşünebiliriz.
11\. # renkleri belirliyoruz
12\. SIYAH = (0, 0, 0)
13\. BEYAZ = (255, 255, 255)
14\. MAVI = (0, 0, 255)
15\. KIRMIZI = (255, 0, 0)
Bu satırlarda ise pygame’de standart olarak belirtilen renklerin değişkenlere atamasını yaptık. RGB (Red, Green, Blue / Kırmızı, Yeşil, Mavi) değerlerinin girilmesi ile değişik renkler de elde edilebilir.
pygame.font.SysFont() fonksiyonu
18\. # yazı karakteri
19\. yaziKarakter = pygame.font.SysFont(None, 48)
Yazı karakterinin belirlenmesi ise pygame.font modülünün içindeki SysFont metodu ile sağlanıyor. İlk parametresi yazı karakterinin ismini isterken ikincisi de yazının büyüklüğünü belirtmemizi istiyor. İlk parametreye “None” yazdığımızda bize varsayılan yazı karakterini veriyor.
render() metodu
# yazıyı oluştur
22\. yazi = yaziKarakter.render('Merhaba Dünya!', True, BEYAZ, KIRMIZI)
23\. yaziRect = yazi.get_rect()
24\. yaziRect.centerx = pencereYuzey.get_rect().centerx
25\. yaziRect.centery = pencereYuzey.get_rect().centery
22. satırda yazı karakterimizi render() metodu ile pencere yüzeyinin üstüne ekliyoruz. Bu metodun ilk parametresi yazımızı, üçüncüsü yazı rengini, dördüncüsü de arkaplan rengini belirtiyor. İkinci değişken ise yazının bulanık mı keskin mi olacağına karar veriyor. Eğer True girersek keskin çizgilerle, False girersek bulanık bir şekilde yazıyor yazımızı.
23. satırda ise get.rect() motodu ile yaziRect’in etrafına bir dörtgen oluşturuyoruz. Bu dörtgenin merkezinin x ve y değerlerini ise 24. ve 25. satırda pencere yüzeyinin merkezinin x ve y değerlerine eşitliyoruz. Bu şekilde “Merhaba Dünya” yazımız pencerenin tam ortasında yer alıyor. yaziRect.centerx gibi yaziRect.left, yaziRect.right, yaziRect.top ve yaziRect.bottom özelliklerini de kullanabiliriz. yaziRect dörtgeni için yaziRect.left sol kenarın ve yaziRect.right sağ kenarın x değerini verirken yaziRect.top üst kenarın, yaziRect.bottom alt kenarın y değerini verir.
fill() metodu
27\. # pencere yüzeyine beyaz arkaplan ekliyoruz
28\. pencereYuzey.fill(BEYAZ)
Bu bölümde ise fill fonksiyonunu çağırarak pencerenin içine ilk defa bir şey ekliyoruz. Bu fonksiyon pygame.display.update() fonksiyonunu çalıştırdığımız zaman pencerenin arkaplanını beyaza boyar ancak pygame.display.update() fonksiyonunu ekrana bir şey çizdikten hemen sonra çağırmak programımızı yavaşlatabilir. Onun yerine ekrana çizeceğimiz her şeyi yazdıktan sonra bir kez bu fonksiyonu çağırmak faydalı olacaktır.
pygame.draw fonksiyonları
30\. # siyah çigi çiziyoruz
31\. pygame.draw.line(pencereYuzey, SIYAH, (90, 90), (150, 90), 5)
pygame.draw.line() fonksiyonu birinci değişkende belirtilen yüzeyin üstüne ikinci değişkendeki renk ile bir çizgi çizer. Bu çizginin başlangıç ve bitiş noktalarının koordinatlarını ise üçüncü ve dördüncü değişken belirler. Son değişkenin kullanımı ise isteğe bağlıdır ve çizginin kalınlığını ayarlar.
33\. # mavi daire çiziyoruz
34\. pygame.draw.circle(pencereYuzey, MAVI, (400, 70), 30, 0)
pygame.draw.circle() fonksiyonu ise yine ilk değişkende belirtilen yüzeye ikinci değişkendeki renk ile çember çizer. Çemberin merkez koordinatını üçüncü değişken, yarıçapını ise dördüncü değişken tanımlar. Son değişken ise çemberin çizgisinin kalınlığını ayarlar fakat bu değişkene 0 değerini verirsek çember yerine daire çizer yani çemberin içini aynı renkle doldurur.
blit() metodu
36\. # yazıyı pencere yüzeyinde oluşturuyoruz
37\. pencereYuzey.blit(yazi, yaziRect)
blit() metodu pygame’de bir yüzey nesnesinin başka bir yüzey nesnesinin üstüne çizmek için kullanılır. Mesela ‘yazi’ değişkeninde tanımladığımız “Merhaba Dünya” bir yüzeydir. Biz de blit() metodunu kullanarak ‘yazi’ yüzeyini ‘pencereYuzey’ yüzeyinin üstünde oluşturuyoruz. İkinci değişkendeki yaziRect ise ‘yazi’ yüzeyinin pencerenin neresinde oluşturulacağını ayarlamamızı sağlıyor.
pygame.display.update() fonksiyonu
39\. # pencereyi ekranda oluşturuyoruz
40\. pygame.display.update()
Bu satıra kadar çizdiğimiz hiçbir şey ekranda oluşturulmamıştı. Biz sadece onları bellekte oluşturmuştuk ve artık ekranda da oluşturmak istiyoruz. Bunun için pygame.display.update() fonksiyonunu kullanıyoruz. Bu fonksiyonu bellekteki işlemlere oranla daha yavaş hareket ettiği için tüm çizimleri bellekte yaptıktan sonra çağırıyoruz. Yani istersek siyah çizgiyi çizdikten sonra ve mavi daireyi çizdikten sonra da birer kez çağırabilirdik ama bu da programımızın daha yavaş çalışmasına neden olurdu.
Oyun döngüsü ve olaylar
42\. # oyun döngüsünü çalıştırıyoruz
43\. while True:
Oyunumuzu yazarken sürekli girdileri kontrol etmemiz gerekecek ve bu girdilere göre oyunumuzda hareketler olacaktır. Mesela yön tuşlarıyla ekranda gezinen bir dörtgen oluşturmak istiyoruz. Bunun için döngü oluşturup sürekli hangi tuşa basıldığını kontrol etmemiz ve ayrıca her döngüde basılan tuşa göre dörtgenimizi ekranda gideceği yerde tekrar oluşturmamız gerekecektir. Bu nedenle oyunumuzda döngü kaçınılmaz bir ihtiyaçtır.
44\. for olay in pygame.event.get():
45\. if olay.type == QUIT:
46\. pygame.quit()
47\. sys.exit()
Döngümüzün içinde ise olayları kontrol ettiğimiz bir bölüm eklememiz gerekmektedir. Şimdilik sadece QUIT olayını kontrol ediyoruz ama yukarıda bahsettiğim gibi tuşa basılıp basılmadığını da kontrol edebiliriz. Eğer kapat tuşuna basılırsa veya pencere bir şekilde kapatılırsa (yani QUIT olayı gerçekleşirse) pygame.quit() ve sys.exit() fonksiyonlarını çalıştırıyoruz. Bu fonksiyonları pencerenin kapatılması durumunda çalıştırmazsak pygame içinde bir sorun yaşanabilir ve tekrar çalışmayabilir bu nedenle her oyunumuzda bu kontrolü yapıyoruz. Bu kontrolü de yaptıktan sonra eğer döngüde başka bir şey yapmıyorsak programımızı tamamlamış oluyoruz.
Bu yazımızda pygame ile oyun yazmak için en çok gereken fonksiyonları öğrendik ve gelecek ayki yazımız için temeli attık. Gelecek yazımızda basit bir araba yarışı oyununun pygame ile nasıl geliştirileceğini anlatacağız.
Gelecek yazımızda görüşmek üzere, hoşçakalın :)