Arcade Türü Oyun Programlamayı ve Bilgisayar Bilimleri Öğrenin

Arcade Türü Oyun Programlamayı
ve Bilgisayar Bilimleri Öğrenin

Chapter 11: Bit Eşlemli Grafikler ve Ses

Daireler ve dikdördgenler çizmek gibi basit şekillerin ötesine geçmek için programlarımız bit eşlemli grafiklerle (bitmapped graphics) çalışma yeteneğine ihtiyaç duyarlar. Bit eşlemli grafikler bir çizim programı tarafından oluşturulmuş ve kaydedilmiş fotoğraf veya resimler olabilir.

Grafikler tek başına insanı saran bir oyun yapmayacaktır. Oyunlar sese ihtiyaç duyar! Burada oyununuzda sesin kullanımıyla tanışacağız.

11.1 Programı Bir Klasörde Depolamak

Şu ana kadar işlediğimiz konularda yer alan programlar sadece bir .py dosyası istiyordu. Görüntüleri ve sesleri dahil edince, oyun geliştirmenin bir parçası haline gelen daha fazla dosya oluyor. Bu dosyaları başka programlarla karıştırmak kolaydır. Bunu engellemenin yolu ise bu daha karışık dediğimiz programların her birini kendi klasörlerinin içerisine koymaktır. Bunun gibi bir projeye başlamadan önce, "yeni klasör" butonuna tıklayın ve bu yeni klasörü oyun için tüm yeni dosyaları koymak için bir yer olarak kullanın.

fig.create_a_folder
Figure 11.1: Yeni bir klasör oluştur

11.2 Arkaplan Resmini Belirlemek

Oyununuz için bir arkaplan resmi mi belirlemek istiyorsunuz? Bu örnekte alttaki resmi kullanacağız. Resme sağ tıklayın ve onu az önce oyununuz için oluşturduğunuz klasöre kopyalayın.

fig.background_image
Figure 11.2: Arkaplan Resmi

Oyunda kullanılan resimlerin hepsi daha önceden ekranda görüntüleneceği boyutlara ayarlanmış olmalıdır. 5000x5000 piksellik bir resmi yüksek çözünürlüktü bir kameradan alıp daha onra 800x600'lük bir pencereye yüklemeye çalışmayın. Bir grafik programı kullanarak (MS Paint bile bu işi yapacaktır) boyutlandırma/kırpma işlemini resmi programda kullanmadan önce yapın.

Resmi yüklemek sadece tek satırdan oluşan basit bir işlemdir. Bu tek satırlık koda gerçekleşen pek çok işlem vardır, dolayısıyla bu satırın açıklaması üç bölümde anlatılacaktır. Bu satırın alttaki versiyonu saturn_family1.jpg adlı dosyayı yükleyecektir. Bu dosya Python programının olduğu dizinle aynı dizinle olmalıdır. Aksi takdirde bilgisayar onu bulamayacaktır.

pygame.image.load("saturn_family1.jpg")

Resmi yüklemek onu ekranda göstermeyecektir. Bu resmi daha sonra kullanabilmek için load() komutunun döndürdüğü çıktıyı bir değişkene atamalıyız. Bu durumda, background_image isimli yeni bir değişken oluşturulur. İkinci versiyon incelemeniz için alttadır:

background_image = pygame.image.load("saturn_family1.jpg")

Son olarak, resim çalışılması daha kolay olan Pygame formatına dönüştürülmelidir. Bunu yapmak için, .convert()'i dönüştürme fonksiyonunu çağırması için komuta ekliyoruz. Bütün resimler bu kalıbı kullanıp, gerektiğinde değişken ismi ve dosya ismi değiştirilerek yüklenmelidir.

background_image=pygame.image.load("saturn_family1.jpg").convert()

Resmin yüklenmesi ana program döngüsünden önce yapılmalıdır. Onu ana program döngüsünde yüklemek de mümkün olduğu halde, bu programın resmi bilgisayarın hafızasından saniyede 20 veya daha fazla kez almasına sebep olacaktır. Bu tamamen gereksizdir. Gerekli olan tek şey program başlangıcında bunu bir kez yapmaktır.

Resmi göstermek için, programlar blit() adı verilen komutu kullanmaktadır. Bu, bitleri ekrana "blitler". Biz bu komutu zaten daha önce yazıyı oyun penceresinde gösterirken kullanmıştık.

blit komutu çağırıldığında, o; resmi, değerleri veya resmin başladığı yeri, yani sol üst koordinatlarını tutan bir değişkene aktarılır. Bu komut, her frame'de resmin çizilebilmesi için ana döngünün içerisinde yer almalıdır. Alta bakın:

screen.blit(background_image, [0,0])

Bu kod background_image'un içinde tutulan görüntüyü (0,0)'dan başlayarak ekrana blit'ler. (Ç.N blit kelimesi orijinalde de bu şekilde kullanılmış, çeviri önerisi için mail atabilirsiniz.)

11.3 Resmi Hareket Ettirmek

Bu bölüm kırmızı bir X'i ekranın etrafında hareket ettirecektir. Bu kırmızı X'in resmi şuradan indirilebilir:

fig.player_image
Figure 11.3: Oyuncu resmi

Ekranın etrafında fare ile hareket edebilen bir resim oluşturmak için, önceki komutla aynı şekilde yükleme yapılır:

player_image = pygame.image.load("player.png").convert()

Ana program döngüsünün içerisinde, fare koordinatları alınır ve resmi çizmek için başka bir blit fonksiyonuna gönderilir:

# O anki fare konumunu al. Bu, konumu
# iki sayılık bir liste olarak döndürür.
player_position = pygame.mouse.get_pos()
x=player_position[0]
y=player_position[1]

# Resmi ekrana kopyala:
screen.blit(player_image, [x,y])

Bu bir sorunu gösteriyor. Resim beyaz arkaplanlı kırmızı bir X. Yani resim çizildiğinde programın gösterdiği:

fig.nontrans_background

Sadece kırmızı X isteniyor. Fakat resimler dikdörtgen şeklindedir ve bazen başka şekiller istenir. Bunun yolu programa bir rengi "transparent" (saydam) yapmasını ve ekranda göstermemesini söylemektir. Bu yüklemenin hemen ardından yapılabilir. Alttaki kod beyaz rengi(white değişkeninin daha önce tanımlandığı varsayılıyor) saydam yapar:

player_image.set_colorkey(white)

Bu .gif ve .png ile biten çoğu dosyada çalışacaktır. Bu çoğu .jpg dosyası için çalışmaz. jpeg dosya formatı fotoğraf tutmak için çok iyidir, fakat bu format kurnazca resmi görüntüyü daha küçük yapan bir algoritmanın bir parçası olarak değiştirir. Bunun anlamı bütün arkaplan resmi aynı olacaktır. Alttaki kodta, X bir jpeg olarak kaydedilmiştir. X'in etrafındaki beyaz tam olarak (255,255,255) değildir, fakat beyaza gerçekten çok yakındır.

fig.jpeg_artifacts
Figure 11.4: JPEG Sıkıştırma Hataları

11.4 Sesler

Bu bölümde bir tıklama sesi kullanılmaktadır. Bu dosya buraya sağ tıklanarak ve "bağlantıyı farklı kaydet" seçeneği kullanılarak (veya "hedefi farklı kaydet" ya da tarayıcınız ona ne isim verdiyse) indirilebilir.

Resimler gibi, sesler de kullanılmadan önce yüklenmelidir. Bu ana program döngüsünden önce bir kez yapılmalıdır. Alttaki komut bir ses dosyasını yükler ve ona referans olması için click_sound isimli bir değişken oluşturur.:

click_sound = pygame.mixer.Sound("click.wav")

Bu ses kullanıcı farenin butonuna alttaki kod çalışırken bastığında çalınabilir:

for event in pygame.event.get():
	if event.type == pygame.QUIT:
		done=True
	if event.type == pygame.MOUSEBUTTONDOWN:
		click_sound.play()

Pygame internette bulunabilecek hiçbir .wav dosyasını çalıştırmaz. Ücretsiz yazılım olan VLC Media Player onu çalamıyorsa, Pygame de çalamaz.

11.5 Kodun Tamamı

"""
 Sample Python/Pygame Programs
 Simpson College Computer Science
 http://programarcadegames.com/
 http://simpson.edu/computer-science/

 Explanation video: http://youtu.be/4YqIKncMJNs
 Explanation video: http://youtu.be/ONAK8VZIcI4
 Explanation video: http://youtu.be/_6c4o41BIms
"""

import pygame

# Define some colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)

# Call this function so the Pygame library can initialize itself
pygame.init()

# Create an 800x600 sized screen
screen = pygame.display.set_mode([800, 600])

# This sets the name of the window
pygame.display.set_caption('CMSC 150 is cool')

clock = pygame.time.Clock()

# Before the loop, load the sounds:
click_sound = pygame.mixer.Sound("laser5.ogg")

# Set positions of graphics
background_position = [0, 0]

# Load and set up graphics.
background_image = pygame.image.load("saturn_family1.jpg").convert()
player_image = pygame.image.load("playerShip1_orange.png").convert()
player_image.set_colorkey(BLACK)

done = False

while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        elif event.type == pygame.MOUSEBUTTONDOWN:
            click_sound.play()

    # Copy image to screen:
    screen.blit(background_image, background_position)

    # Get the current mouse position. This returns the position
    # as a list of two numbers.
    player_position = pygame.mouse.get_pos()
    x = player_position[0]
    y = player_position[1]

    # Copy image to screen:
    screen.blit(player_image, [x, y])

    pygame.display.flip()

    clock.tick(60)

pygame.quit()

11.6 Tekrar

Alttaki Python programları ekrana ne yazdırır?

  1. def f():
        return 10
    
    x=f()
    print (x)
    
  2. def f(x):
        x=x+10
        return x
    
    x=10
    f(x)
    print (x)
    
  3. def f(x):
        x=x+10
        return x
    
    def g(x):
        return x*2
    
    print ( f( g(10) ) )
    
  4. def f(x):
        x=x+10
        return x
    
    def g(x):
        return x*2
    
    print ( g( f(10) ) )
    
  5. def f(x,y):
        return x/y
    
    x=20
    y=5
    print ( f(y,x) )
    
  6. def f(x):
        return x*2
    
    def g(x):
        return x-2
    
    def h(x):
        return x+10
    
    print ( f(5) + g(f(5)) + h(g(10)) )
    print ( h(g(f(10))) )
    
  7. x=len( [2,3,[5,6],[7,9]]
    print (x)
    
  8. Ekrana "Merhaba" yazdıran bir fonksiyon yazın.
  9. Önceki sorudaki fonksiyonu çağırın.
  10. Bir string alıp içerisindeki boşluk karakterlerini sayan fonksiyon yazın.
  11. Bir dizi alan ve her elemanını ayrı ayrı ekrana yazdıran bir fonksiyon yazın.
  12. Bir dizi alan ve toplamını döndüren bir fonksiyon yazın.

You are not logged in. Log in here and track your progress.