PyGame Maymun

Bu örnekte hareket eden bir şempanzeye vurmaya çalışıyoruz. Arkada vurduğumuz takdirde para kazanacağımızı söyleyen bir reklam var. Bu örnekte kodu parça parça inceleyip PyGame’in nasıl çalıştığını daha iyi anlamaya çalışacağız. Orjinal dökümana bu adresten ulaşabilirsiniz(ingilizcedir).

Modülleri Import Edelim

import os, sys
import pygame
from pygame.locals import *

if not pygame.font: print 'Warning, fonts disabled'
if not pygame.mixer: print 'Warning, sound disabled'

İlk satırda os ve sys modüllerini çağırdık bunlar platformdan bağımsız dosya yollarını belirleme gibi işlemlerde kullanılıyor.
İkinci satırda pygame import edildi ardındansa local bölümünden kullanışlı bazı fonksiyonlar modüller yükleniyor. Alttaki kısımda ise hata mesajları var eğer font ve ses modülleri yüklenememişse bu hatalar verilecek.

Kaynakları Yükleyelim


def load_image(name, colorkey=None):
fullname = os.path.join('data', name)
try:
image = pygame.image.load(fullname)
except pygame.error, message:
print 'Cannot load image:', name
raise SystemExit, message
image = image.convert()
if colorkey is not None:
if colorkey is -1:
colorkey = image.get_at((0,0))
image.set_colorkey(colorkey, RLEACCEL)
return image, image.get_rect()

Yukar ki kısımda ise oyun için gerekli kaynakları yüklüyoruz. Colorkey özelliği none olarka ifade edilmiş, saydam grafikler için kullanılan bir özellikmiş bu…
Alt kısımda image.load işlemi yapımış. Bir önceki yazıda bahsettiğimiz gibi load() can kurtaran gibi yetişiyor 🙂 Load() hadisesini birde try,except hata sistemine sokmuşuz eğer image.load edilemezse hata mesajı alacağız. Ardından bir convert() işlemi yapmışız bu resmin renk formatını ve derinliği kopyalayıp ekrana oldukça hızlı bir şekilde vermemize yarayacak. Ardından colokey konusuna bir dönüş yapıyoruz. Eğer kullanıcı colorkey için bir argüman sağlarsa biz bu değişkeni resmin colorkey değeri olarak kullanıyoruz. Burada -1 şeklinde bu işlemi geçiştirirsek program ekranın sol üst kısmındaki pixele bakarak oradaki değeri atar. Şimdi sesleri yükleyelim:


def load_sound(name):
class NoneSound:
def play(self): pass
if not pygame.mixer:
return NoneSound()
fullname = os.path.join('data', name)
try:
sound = pygame.mixer.Sound(fullname)
except pygame.error, message:
print 'Cannot load sound:', wav
raise SystemExit, message
return sound

Yukarda ne yapıldığına gelirse şimdi program önce mixer modülünün yüklenip yüklenmediğine bakıyor eğer yüklenmemişse sessiz şekilde çalışıyor eğer yüklenmişse uygulamam normal şekilde çalışıyor.

Oyun Obje Sınıfları

class Fist(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image, self.rect = load_image('fist.bmp', -1)
self.punching = 0

def update(self):
pos = pygame.mouse.get_pos()
self.rect.midtop = pos
if self.punching:
self.rect.move_ip(5, 10)

def punch(self, target):
if not self.punching:
self.punching = 1
hitbox = self.rect.inflate(-5, -5)
return hitbox.colliderect(target.rect)

def unpunch(self):
self.punching = 0

Yukarısı biraz karışık oldu biliyorum biraz daha açalım o zaman. Yukarıda yaptığımız oyuncunun yumruğunu oluşturmak. update metodu yumruğun faremizi takip etmesi için kullanıyor pos = pygame.mouse.get_pos() ile farenin pozisyonunu alıyoruz.


class Chimp(pygame.sprite.Sprite):
"""maymunu karşı tarafa geçirir vurursa döndürür"""
def __init__(self):
pygame.sprite.Sprite.__init__(self) #call Sprite intializer
self.image, self.rect = load_image('chimp.bmp', -1)
screen = pygame.display.get_surface()
self.area = screen.get_rect()
self.rect.topleft = 10, 10
self.move = 9
self.dizzy = 0

def update(self):
"yürüme veya dönme, maymunun durumuna göre"
if self.dizzy:
self._spin()
else:
self._walk()

def _walk(self):
"maymunu ekranın karşısına getirir oradan da geri döndürür"
newpos = self.rect.move((self.move, 0))
if not self.area.contains(newpos):
if self.rect.left < self.area.left or
self.rect.right > self.area.right:
self.move = -self.move
newpos = self.rect.move((self.move, 0))
self.image = pygame.transform.flip(self.image, 1, 0)
self.rect = newpos

def _spin(self):
"maymun resmini hareket ettirir, döndürür"
center = self.rect.center
self.dizzy += 12
if self.dizzy >= 360:
self.dizzy = 0
self.image = self.original
else:
rotate = pygame.transform.rotate
self.image = rotate(self.original, self.dizzy)
self.rect = self.image.get_rect(center=center)

def punched(self):
"maymuna vurulduğunda dönüşe başlattıracak"
if not self.dizzy:
self.dizzy = 1
self.original = self.image

Gittikeç karmaşıklaşıyor 🙂 bende anlatmakta zorlanıyorum ama ne demiş babaşakanımız “durmak yok yola devam!” Gördüğünüz gibi chimp sınıfı yumruğa göre daha fazla iş yapıyor. Bu sınıf maymunu hareket ettiriyor oyunda maymuna vurunca maymun dönüyor ve hızlanıyor ardından tekrardan normale dönüyor.

Kullanıma Hazırlayalım


pygame.init()
screen = pygame.display.set_mode((468, 60))
pygame.display.set_caption('Monkey Fever')
pygame.mouse.set_visible(0)


Arka Planı Oluşturalım

Ekranımızla aynı ölçüde bir bg oluşturuyoruz. ardından convert() yardımıyla bu ekran ile bg’ın aynı formatta olduğunu deklare ediyoruz. fill() ilede RGB rengini belirliyoruz o üç argüman rengi belirtiyor.(beyaza kaçan bir renk)

background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((250, 250, 250))

Arka Plana Yazıyı Oturtalım
öncelikle pygame.font modülünün yüklenmiş olduğundan emin olmamız lazım yoksa bu adımı geçiniz efendim. önce font objesini oluşturmamız ardından bunu yeni yüzeyimize render etmemiz gerekiyor. fontu oluştururken normalde none yerine font tipinizi yazabilirsiniz şimdi biz none değeri vererek default font’u kullanıyoruz. ardından rect objesi yardımıyla ortalıyoruz ardındn blit metoduyla yazımızı backgroun’a kopyalamış oluyoruz(blit kopyala/yapıştır işini görüyor)

if pygame.font:
font = pygame.font.Font(None, 36)
text = font.render("Pummel The Chimp, And Win $$$", 1, (10, 10, 10))
textpos = text.get_rect(centerx=background.get_width()/2)
background.blit(text, textpos)

Arka Planı Yükleyelim

screen.blit(background, (0, 0))
pygame.display.flip()

Objeleri Kullanıma Hazırlayalım
Iskalama sesini ve vuruş sesini sırayla yüklüoyurz. Ardından maymunu sonrada yumruğu kullanıma hazırlıyoruz. Clock objesi oyunun frame rateini kontrol etmemizi sağlıyor. allsprite adında bir grup oluşturarak bunu RenderPlanin grubuna bağlıyoruz RenderPlain tüm çizimlerin ekrana dökülmesini sağlıyor. Daha gelişmiş Render grupları mevcut ama bu örnekte sadece basit çizimler kullanıyoruz.

whiff_sound = load_sound('whiff.wav')
punch_sound = load_sound('punch.wav')
chimp = Chimp()
fist = Fist()
allsprites = pygame.sprite.RenderPlain((fist, chimp))
clock = pygame.time.Clock()

Main Loop
Burda pek bişi yapılmıyor saniyeden 60 frameden hızlı olmamasını sağladık oyunun.

while 1:
clock.tick(60)

Tüm verigirişlerini halledelim
Aşağıda artık veri girişlerini hallediyoruz, vuruş kısmına dikkat ses ekliyoruz 😉

for event in pygame.event.get():
if event.type == QUIT:
return
elif event.type == KEYDOWN and event.key == K_ESCAPE: #Esc basınca oyundan çık
return
elif event.type == MOUSEBUTTONDOWN:
if fist.punch(chimp):
punch_sound.play() #vurduysak bu ses çıkacak
chimp.punched()
else:
whiff_sound.play() #ıskaladıysak bu ses çıkacak
elif event.type == MOUSEBUTTONUP:
fist.unpunch()

Spriteları Güncelle(sprite konusuna da gelicez)
Sprite modülü update() metoduna sahip bu sayede tüm objeler etrafta dönmeye başlayacak. Maymun bir köşeden diğerine gidecek vurduğumuzda dönecez

allsprites.update()

Sahneyi Çizelim
Objeler doğru yerdeler, şimdi sıra onları çizmeye geldi. İlk blit arka planı çiziyor.draw() ile screen’i çiziyoruz son olarak flip() ile çizdiğimiz herşeyi ekrana vermiş oluyoruz.

screen.blit(background, (0, 0))
allsprites.draw(screen)
pygame.display.flip()