23
Kas

Xml verilerini işlemek için çeşitli yapılar vardır(dom, sax gibi). Bu derste ağaç yapısını kullanan ElementTree modülünü öğreneceğiz ve hız ve performans bakımından C ile yazılmışı olan cElementTree modülünü kullanacağız.

Bu modül xml.etree modül paketinin bir parçasıdır. Modülümüzü farklı şekillerde çağırabiliriz.

from xml.etree import cElementTree
import xml.etree.cElementTree as cElementTree

Öncelikle xml etiketi oluşturmayı ve bu etiketlere nitelik ve değer atamasını öğrenelim.

from xml.etree import cElementTree

root = cElementTree.Element("diller")

child = cElementTree.SubElement(root, "dil")
child.text = "Python"

child = cElementTree.SubElement(root, "dil")
child.text = "Ruby"


Element methoduyla root etiketimizi “diller” adıyla oluşturduk. Çocuk etiket olarak SubElement methodundan faydalandık ve ilk parametresine root değişkenini yazarak ebeveyn etiketini belirledik ve çocuk etiketimizin adını “dil” olarak belirledik. SubElement’in text niteliğini kullanarak etiketimizin değerini “Python” ve sonraki tanımlamamızda “Ruby” olarak girdik.

cElementTree.dump(root)

koduyla xml çıktısı alabiliriz.

<diller><dil>Python</dil><dil>Ruby</dil></diller>

Eğer etiketlerimize nitelikte eklemek istersek Element methoduna ikinci, SubElement methoduna üçüncü bir parametreyi sözlük tipinde veri girerek ekleyebiliriz.

from xml.etree import cElementTree

root = cElementTree.Element("diller", {"type":"script"})

child = cElementTree.SubElement(root, "dil", {"version":"3.2"})
child.text = "Python"

child = cElementTree.SubElement(root, "dil")
child.text = "Ruby"

cElementTree.dump(root)
<diller type="script"><dil version="3.2">Python</dil><dil>Ruby</dil></diller>

Methodlara parametre olarak girmek yerine methodların attrib niteliğine sözlük verisini girebileceğiniz gibi set() methoduyla da nitelik ekleyebilirsiniz.

child.attrib = {"version":"3.2"}
child.set("version", "3.2")
[python]

Bir etiketin niteliğinin taşıdığı veriye ihtiyaç duyarsanız;

[python]
child.get("version")

gibi bir kod ile veriye ulaşabilirsiniz.

cElementTree.dump() sys.stdout ile yazdırır. Bir değer döndürmez. Bunun için cElementTree.tostring() fonksiyonunu kullanmalısınız.

Eğer etiketteki tüm nitelik ve değerlerine ulaşmak isterseniz items() sadece nitelik adına ulaşmak isterseniz de keys() methodunu kullanabilirsiniz.

print child.items()

[("version", "3.2")]

print child.keys()

["version"]

SubElement kullanmak istemiyorsanız, oluşturduğunuz çocuk Element nesnelerini ebeveyn Element nesnesinin append() methodu ile birer birer, ya da extend() methoduna liste olarak gireceğiniz Element nesneleriyle toplu olarak ekleyebilirsiniz.

Ekleyeceğiniz Element’in sırasını belirlemek isterseniz de insert() methodunu kullanabilirsiniz

root.insert(0, child)

Bu kod ile root’a eklenen child ilk sıraya eklenmiş olacaktır.

Kendinize göre bir xml verisi hazırladınız ve bir etiketin çocuğu olan etiketlerin bir listesini almak istediniz. Bunu getchildren() methodu ile alabilirsiniz. Eğer bir etiketin çocuk etiketi varsa Element nesnelerinden oluşan bir liste dönecektir; aksi halde boş bir liste döner. Eğer o çocuk etiketlerinde çocuk etiketi varsa ayrıca o Element nesnelerininde getchildren() methodunu çağırmalısınız.

Silmek istediğiniz bir SubElement nesnesi var ise Element nesnenizin remove() methoduna SubElementi girmelisiniz.

Öğreneceğimiz bir kaç methodu ise örnekle anlatalım ve bunu yaparken de başka şeylerde öğrenelim…

Örneğin elimizde bir xml dosyası var ya da internetten bir xml verisi çekeceğiz. Dışarıdan alınan xml verisini nasıl parse edeceğimizi ve Element’in kalan methodlarını da öğrenelim.

Elimizde şöyle bir xml verisi olduğunu varsayarak kodumuzu yazalım;

<urlset>
    <url>
        <loc>http://www.metehan.us/</loc>
        <lastmod>2011-11-20T19:43:57+00:00</lastmod>
        <changefreq>daily</changefreq>
        <priority>1.0</priority>
    </url>
    <url>
        <loc>http://www.metehan.us/parcala-buyuk-boyutlu-dosyalari-boler-birlestirir-ve-kontrol-eder.html</loc>
        <lastmod>2011-11-20T19:43:57+00:00</lastmod>
        <changefreq>daily</changefreq>
        <priority>0.8</priority>
    </url>
    <url>
        <loc>http://www.metehan.us/python-kurulum-betigi-hazirlamak.html</loc>
        <lastmod>2011-10-16T22:07:54+00:00</lastmod>
        <changefreq>daily</changefreq>
        <priority>0.8</priority>
    </url>
    <url>
        <loc>http://www.metehan.us/qlineedit-ile-otomatik-ve-sekme-iletamamlama.html</loc>
        <lastmod>2011-09-23T18:42:40+00:00</lastmod>
        <changefreq>daily</changefreq>
        <priority>0.8</priority>
    </url>
    <url>
        <loc>http://www.metehan.us/qsettings-sinifi-kullanimi.html</loc>
        <lastmod>2011-09-14T11:59:34+00:00</lastmod>
        <changefreq>daily</changefreq>
        <priority>0.8</priority>
    </url>
</urlset>

bu veriyi ayrıştıracağız ve düzenli bir şekilde çıktısını alacağız…

#-*- coding: utf-8 -*-
from xml.etree import cElementTree

xmlVerisi = open("sitemap.xml").read()
xmlParse = cElementTree.XML(xmlVerisi)
urlTagList = xmlParse.findall("url")

for urlTag in urlTagList:
    print "URL: %s"%urlTag.find("loc").text
    print "Tarih: %s"%urlTag.find("lastmod").text
    print "Değişme Zamanı: %s"%urlTag.find("changefreq").text
    print "Öncelik: %s"%urlTag.find("priority").text
    print "--------------------------------\n"

Örnek kodumuz bu… sitemap.xml dosyasını okuyup XML() fonksiyonuna parametre olarak xml verisini girdik ve parse işlemini gerçekleştirmiş olduk. Bu fonksiyon geriye bir Element nesnesi döndürür. Bu Element nesnesi root etiketi taşır; yani örnek verimizse “urlset” etiketi. Xml verisindeki url etiketine sahip olanlar findall() methoduyla liste olarak aldık ve bir for döngüsü oluşturduk. Bu döngüde url etiketinin çocuğu olan loc, lastmod, changefreq ve priority etiketlerini find() methodu ile taşıdığı veriyi aldık. Örnekten de anlaşılacağı gibi find() methodu tek bir sonuç döndürüyor(aynı etiketten fazla olsa da ilk sıradakini alır).

Son olarak ise bu modülle oluşturulan xml verilerinin çıktısı okunabilir olmuyor. Okunabilirlik için Kaynak‘tan ikinci bağlantıyı inceleyebilirsiniz.

Kaynak: The ElementTree XML API
ElementTree ile XML oluşturmaya giriş

Bu yazı Creative Commons-BY-SA ile lisanslanmıştır. Bu yazıyı ilk sahibini belirtmek ve aynı lisansla dağıtmak koşuluyla kullanabilirsiniz.

Benzer yazı yok.

16
Eki

Python ile ilginenler, en azından bir kaç kez üçüncü şahısların yazdığı modüllerden yüklemiştir ve bu modülü yüklerken modülle birlikte gelen setup.py betiğini build ve/veya install parametresiyle çalıştırmıştır. Bu kurulum betiği sayesinde geliştiriciler zaman kaybetmeden modülü kullanılabilir hale getirir… Biz de bu yazıda işimizi yeteri kadar görecek şekilde kurulum betiği dosyası hazırlamayı öğreneceğiz. Bu yazıdan kısa süre önce ilk defa kurulum betiği hazırlamış oldum…

Zorunlu olmasa da genel olarak kurulum betiğine setup.py adını veriyoruz ve bu yazı da kurulum betiğimizi bu dosyada hazırlayacağız.

Bir kurulum betiği hazırlamak için Python ile gelen distutils modülünü kullanıyoruz.

from distutils.core import setup

setup()

distutils.core modülünde bulunan setup fonksiyonunu kullanarak modülümüzle ilgili gerekli bilgileri girmemiz gerekiyor.

Örneğin hede.py adında tek dosyadan oluşan bir modülümüz var. Bunun kurulum betiğini oluşturalım…

from distutils.core import setup

setup(
    name = "hede",
    py_modules = ["hede"],
    version = "1.0",
  • name parametresi uygulamanın adını belirtir.
  • py_modules parametresine liste olarak girilen isimler *.py dosyalarının uzantısız hali olmalıdır. Bu parametre tekil modülleri bekler.
  • version parametresi ise uygulamanızın versiyonunu belirtir.

name ve version parametreleri, uygulamanızı easy_install ve/veya pip ile kurulabilmesi için pypi.python.org/pypi adresinde yayınlamanızda gereklidir. Şimdi setup.py dosyasının olduğu dizine konsol ile girin ve;

python setup.py sdist

komutunu verin. Bulunduğunuz dizinde dist adında bir dizin ve içinde hede-1.0.tar.gz adlı bir dosya oluşacaktır. Daha sonra bu dosyayı pypi.python.org/pypi adresinde nasıl yayınlayacağımızı göreceğiz…

hede.py modülünü kurmak için de;

python setup.py install

komutunu verebilirsiniz. Windows kullanıcıları için binary dosya oluşturmak için;

python setup.py bdist_wininst

Fedora, Mageia gibi rpm paket sistemini kullanan kişiler için;

python setup.py bdist_rpm

komutunu verebilirsiniz. Windows kullanıcıları için Linux altında da binary(*.exe) oluşturmak mümkün. Ancak bunun için Python’un geliştiriciler için olan paketini kurmanız gerekmektedir. Ubuntu da python-dev ismiyle bulup kurmak mümkün. Diğer GNU/Linux dağıtımlarında da ismi büyük ihtimal aynıdır…

Aynı şekilde rpm paketi oluşturmak içinde python-dev paketinin kurulu olması gerekebilir…

Uygulamamızı biraz daha geliştirelim. lib adında bir modül paketi oluşturup(İçinde __init__.py olan bir dizin) içine hedelib.py ve hodolib.py modüllerini ve lib2 adında bir modül paketi oluşturup içine hedelib2.py adlı bir modül oluşturduğumuzu varsayalım.

hede.py
lib/
    lib2/
        __init__.py
        hedelib2.py
    __init__.py
    hedelib.py
    hodolib.py

Uygulamamızda modül paketi varsa setup() fonksiyonuna packages parametresini ekleyip paketlerin ismini içeren bir liste girmeliyiz.

from distutils.core import setup

setup(name='hede',
      version='1.0',
      description='Python hede kütüphanesi',
      author='Metehan Özbek',
      author_email='metehan [at] metehan.us',
      url='http://www.metehan.us',
      packages=['lib', 'lib.lib2'],
     )

Python paket indeksinde gözükmesi içinde url, author, author_email ve description parametrelerini girdik.

python setup.py install

Komutunu verdiğinizde Python’un kütüphanelerinin bulunduğu dizin içerisindeki site-packages(Ubuntu da dist-packages) dizininde; hede.py ve lib modül paketi içinde, lib2 dizini ve modüllerle beraber yüklenecektir. Bu durumda Python yorumlayıcısında modülünüzü şu şekilde çağırabilirsiniz:

import hede
from lib.lib2 import hedelib2
from lib import hedelib, hodolib

Tabii lib ismi çok kullanıldığından bir ihtimal çakışma olabilir. Bunu önlemek için ana modül paketinizi hede yapmanız daha doğru olacaktır.

from hede import hede
from hede.lib.lib2 import hedelib2

Uygulamanızda çalıştırılabilir bir betik oluşturmak isteyebilirsiniz. Oluşturduğunuz betiği(ör: hede) konsoldan hede yazarak çalıştırmak isteyebilirsiniz. setup() fonksiyonuna gireceğiniz scripts parametresiyle liste olarak girdiğiniz betikleri GNU/Linux ortamında /usr/bin/ altına Windowsta ise Python’un kurulduğu dizin içerisindeki Scripts dizinine yazdırabilirsiniz. Yalnız Windowsta betiğinizi çalıştırabilmek için bir *.bat dosyası ile betiğinizi çalıştırmanız gerekmektedir(ör: hede için hede.bat) ve path e ekli olmadığından cmd ile betiğinizi çalıştıramazsınız.

hede.py
script/
    hede
lib/
    lib2/
        __init__.py
        hedelib2.py
    __init__.py
    hedelib.py
    hodolib.py
from distutils.core import setup

setup(name='hede',
      version='1.0',
      description='Python hede kütüphanesi',
      author='Metehan Özbek',
      author_email='metehan [at] metehan.us',
      url='http://www.metehan.us',
      packages=['lib', 'lib.lib2'],
      scripts=["script/hede"]
     )

Uygulamız gelişti ve resim, ses dosyası gibi veriler ekledik. Dizin içindeki verileri almak için data_files, modül paketi içindeki veri dizinlerini almak için package_data parametrelerini kullanırız. Yeni dizin-dosya yapımız şöyle olsun:

hede.py
data/
    veri.db
script/
    hede
lib/
    lib2/
        data/
            simge.png
        __init__.py
        hedelib2.py
    __init__.py
    hedelib.py
    hodolib.py

Bu dosya-dizin yapısına göre veri dosyalarımızı kurulum betiğimize ekleyelim.

from distutils.core import setup

setup(name='hede',
      version='1.0',
      description='Python hede kütüphanesi',
      author='Metehan Özbek',
      author_email='metehan [at] metehan.us',
      url='http://www.metehan.us',
      packages=['lib', 'lib.lib2'],
      scripts=["script/hede"],
      data_files=[("data", ["veri.db"])],
      package_data={"lib.lib2":["data/*"]}
     )

Görüldüğü üzere data_files bir liste verisi alıyor. Listenin her elemanı birer tuple. Tuple ilk elemanı dizin, ikinci elemanı ise dosya ismidir. package_data ise bir sözlük veri tipi alıyor ve her elemanın anahtar ögesi modül paketi ismi, değer ögesi ise liste olarak dizin ve dosya alıyor. Burada düzenli ifadelerin kullanımıda mümkün(regex).

setup.py betiğini çalıştırırken kullandığımız sdist argümanıyla uygulamanızın sıkıştırılmış halini alıyorsunuz. Bu dosya içerisinde bulunmasını istediğiniz ek dosyaları MANIFEST.in adlı dosya da tanımlayabilirsiniz. Buradan kullanılabilir kodları öğrenebilirsiniz.

setup() fonksiyonunun alabileceği tüm parametrelere buradan ulaşabilirsiniz. Temel olarak bir kurulum betiğini hazırlamayı öğrendiğimize göre artık modülümüzü-uygulamamızı Python Package Index sayfasına yollayalım…

setup.py betiğimizin bulunduğu dizine konsol ve/veya cmd ile geliyoruz ve

python setup.py register

diyoruz. Bizden dört adet seçenekten birini seçmemizi istiyor.

running register
running check
We need to know who you are, so please choose either:
 1. use your existing login,
 2. register as a new user,
 3. have the server generate a new password for you (and email it to you), or
 4. quit
Your selection [default 1]:

Daha önce pypi ye üye olmadıysanız 2 yazıp kayıt işlemini gerçekleştirebilirsiniz. Ben önceden kayıt olduğum için 1 yazıp devam ediyorum…

İkinci aşamada kullanıcı adı ve şifremizi soruyor ve sırayla gerekli bilgileri giriyoruz. Ardından kullanıcı bilgilerimizi kayıt edeyim mi diye soruyor. Yanıtı y diye verirseniz uygulamanızı güncelleyip yollamak istediğinizde kullanıcı adı ve şifre girmekten muaf olursunuz.

Username: mthnzbk
Password:
Registering parcala to http://pypi.python.org/pypi
Server response (200): OK
I can store your PyPI login so future submissions will be faster.
(the login will be stored in /home/metehan/.pypirc)
Save your login (y/N)?y

Buraya kadar sadece uygulamamızı pypi sayfasına kayıt ettirmiş olduk. Şimdi ise uygulamamızı arşivleyip ya da çalıştırılabilir hale getirip uygulama sayfasında yayınlayalım.

python setup.py sdist upload

ya da

python setup.py bdist_wininst upload
python setup.py bdist_rpm upload

Bir aksilik olmazsa uygulamanız, uygulama sayfanızda gözükmek üzere yüklenecektir…

Kaynaklar:
http://docs.python.org/distutils/setupscript.html
http://docs.python.org/install/index.html
http://docs.python.org/distutils/apiref.html

Buraya bakarlar:
http://docs.python.org/distutils/configfile.html
http://docs.python.org/distutils/sourcedist.html
http://docs.python.org/distutils/builtdist.html
http://pypi.python.org/pypi?:action=list_classifiers

Bu yazı Creative Commons-BY-SA ile lisanslanmıştır. Bu yazıyı ilk sahibini belirtmek ve aynı lisansla dağıtmak koşuluyla kullanabilirsiniz.

Benzer Yazılar:

  1. Python da Kaynak Kodları Gizlemek
  2. Python Kodlarını Derlemek
2
Eyl

Bir çok kez PyQt de QProgressBar’ı uygulama donmadan ilerletmek için QThread kullanmayı denedim, ama her seferinde uygulama çöküyordu. Bunun sebebini öğrenmek ve çözümünü bulmak için zamanında çok araştırma yapmıştım ve ODUN projesiyle uğraşırken çözümü bulmuştum. Aradan zaman geçti ve bu sefer Virux projemde QThread ve QProgressBar kullanmam icap etti. Zaman aralığı çok olduğundan çözümü unutmuştum ve aynı hataları almamla timer event kullanmak zorunda kaldım. Bugün jeton düştü ve ODUN projesinde ilgili koda bakarak nasıl yaptığımı tekrar hatırladım ve yeni sinyal yapısıyla cebelleştikten sonra uygun bir kodla sorunumu hallettim.

Bu konuda QProgressBar’ın uygulamayı dondurmadan ve çökertmeden nasıl kullanacağımızı göreceğiz… Öncelikle basit bir dialog oluşturup QProgressBar ekleyeceğiz ve uygulama çalıştığında QThread sayesinde ilerlemesini sağlayacağız.

import sys
from PyQt4.QtGui import QDialog, QApplication, QProgressBar
from PyQt4.QtCore import QThread

class Thread(QThread):
    def __init__(self, parent):
        QThread.__init__(self, parent)
        self.parent = parent
        self.sayac = 0

    def run(self):
        while self.sayac<1000000:
            self.parent.progress.setValue(self.sayac)
            self.sayac += 1

class Dialog(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.resize(400,250)
        self.progress = QProgressBar(self)
        self.progress.setGeometry(100,75,200,25)
        self.progress.setProperty("value", 0)
        self.progress.setMaximum(1000000)
        self.thread = Thread(self)
        self.thread.start()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    gui = Dialog()
    gui.show()
    sys.exit(app.exec_())

Dialog sınıfımızda dialogumuzu oluşturduk ve QProgressBar’ı ekledik. setGeometry() methodu ekrandaki konumunu ayarlamayı, setProperty() methodu ile QProgressBar’ın nasıl ilerleme yapacağını(%0-%100, 1/100 gibi), setMaximum() methodu ile de ilerleyişin en fazla hangi rakama kadar çıkacağını ayarladık. Yukarıda oluşturduğumuz Thread sınıfımızı tanımladık ve start() methodu ile de süreçi başlatmış olduk.

Thread sınıfını olabilecek en basit şekilde oluşturmaya çalıştım. Dialog sınıfında kullandığımız start() methodu Thread sınıfımızdaki run() methodunu çalıştıracaktır. Biz bu run() methodunda bir while döngüsü oluşturduk ve sayacı her döngüde +1 artırarak sonucu QProgressBar’ın setValue() methodu aracılığıyla aktardık.

Gayet basit, ama bir kaç tesadüf dışında anlam veremediğiniz hata çıktılarıyla uygulamanızın çöktüğünü göreceksiniz. Buna neden olan şey ise tek satır koddur:

self.parent.progress.setValue(self.sayac)

Nedenini bilmeme rağmen bu kodun varlığı hata oluşmasına ve uygulamanın ölmesine-çökmesine neden oluyor. Bu yüzden hatasız bir ilerleme için döngü içinde bu kodu kullanmayacağız…

QThread’ın msleep() methodu ile milisaniye olarak döngü arasında bekletme yaparak ilerleme çubuğunun hareket etmesini izleme fırsatı yakalayabilirsiniz, ama %99 ihtimal ile çökme yaşayacaksınız. Bu sorunu ortadan kaldırmak için kendi sinyalimizi oluşturacağız(PyQt ye yabancıysanız konuyu bile okumayın bence ;) ). Ve sinyalimizin bir değeri yaymasını sağlayacağız. Dialog sınıfında yazacağımız kod ile bu sinyali yakalayıp taşıdığı değeri QProgressBar’a aktaracağız. Bunu radyo sinyalini yakalayıp sesi duymaya benzetebiliriz…

import sys
from PyQt4.QtGui import QDialog, QApplication, QProgressBar
from PyQt4.QtCore import QThread, SIGNAL

class Thread(QThread):
    def __init__(self, parent):
        QThread.__init__(self, parent)
        self.parent = parent
        self.sayac = 0

    def run(self):
        while self.sayac<1000000:
            self.emit(SIGNAL("setValue(int)"), self.sayac)
            self.sayac += 1

class Dialog(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.resize(400,250)
        self.progress = QProgressBar(self)
        self.progress.setGeometry(100,75,200,25)
        self.progress.setProperty("value", 0)
        self.progress.setMaximum(10000)
        self.thread = Thread(self)
        self.thread.start()

        self.connect(self.thread, SIGNAL("setValue(int)"), self.progress.setValue)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    gui = Dialog()
    gui.show()
    sys.exit(app.exec_())

Thread sınıfımızda yukarıda söylediğimiz kodu çıkardık ve QThread’ın emit() methodunu kullandık. İlk parametreye SIGNAL() i kullanarak yayılacak sinyalin adını belirledik ve son parametreye ise yayılacak bilgiyi girdik. Biz burada tek bilgi yaymasını sağladık, ama bunu çoğaltabilirsiniz…

Dialog sınımızda self.thread.start() kod parçasıyla sürecimizi başlattık ve sinyay yaymaya başladık. QDialog’ sınıfının connect() methodu ile bu işlemi gerçekleştirdik. İlk parametreye hangi nesnenin sinyalini dinleyeceğimizi yazdık; ikinci parametrede ise hangi sinyali dinleyeceğimizi; son parametremizde ise sinyalin taşıdığı bilgiyi nereye aktaracağımızı yazdık. setValue() methodu tek parametre aldığına göre ve “setValue(int)” sinyali tek bilgi taşıdığına göre taşınan bilgi QProgressBar’ aktarılmış oldu ve sorunsuz bir şekilde ilerleme çubuğunun ilerleyişini görme imkanımız doğdu.

Ek olarak sinyal ismine bakıpta fonksiyon ismi gibi bir isim vermek, kaç bilgi taşıyacaksa o kadar argüman yazmak(“setValue(int1, int2, intN)” gibi…) gibi bir zorunluluk varmış sanmayın. Bu şekilde sinyalimiz hem anlaşılır, hemde şık durmuş oluyor…

PyQt ile ilgili sorularınıza ileri düzey olmadığı sürece yanıtlamaya çalışabilirim…

Yazım hatası varsa bildiriniz.
Bu yazı Creative Commons-BY-SA ile lisanslanmıştır. Bu yazıyı ilk sahibini belirtmek ve aynı lisansla dağıtmak koşuluyla kullanabilirsiniz.

Benzer Yazılar:

  1. Virux – GNU/Linux için bir antivirüs yazılımı :P
16
Ağu

pygame.rect modülünde kullandığımız çarpışma kontrolünü pygame.sprite modülünün sağladıklarıyla daha etkili bir şekilde yönetebiliriz. Sprite nesneleri kullandığımız için bu araçları kullanırken Sprite ve gruplarını kullanmış olacağız.

Dikdörtgensel bir Sprite nesnesinin başka bir Sprite nesnesi ile çarpışmasını collide_rect fonksiyonu ile kontrol edebiliriz.

pygame.sprite.collide_rect(Sprite1, Sprite2)

Çarpışma varsa bu fonksiyon geriye True değeri döndürecektir. Aksi halde False değerini döndürecektir.

Dairesel Sprite nesnelerinin çarpışma kontrolünü ise collide_circle() fonksiyonu ile kontrol ediyoruz. Bu fonksiyonuda collide_rect() fonksiyonu ile aynı şekilde kullanıyoruz…

Bu iki fonksiyon ile bir Sprite ın olağan rect değerine göre kontrol sağlanıyor. Eğer bir Sprite nesnesinin çarpışma alanını genişletmek isterseniz collide_rect_ratio ile collide_circle_ratio sınıflarını kullanmalısınız…

pygame.sprite.collide_rect_ratio(2.0)(Sprite1, Sprite2)
pygame.sprite.collide_circle_ratio(1.5)(Sprite1, Sprite2)

Bu sınıflar ilk verilen Sprite nesnesinin dikdörtgensel alanını ya da dairesel olarak çapını değiştirmenizi ve bu yeni değerlerle çarpışma kontrolünü yapmanızı sağlar. Bu sınıfların kullanımı size garip gelebilir, eğer gelirse şu yöntemi kullanarak daha anlaşılır kılabilirsiniz.

collide_rect = pygame.sprite.collide_rect_ratio(2.0)
collide_rect(Sprite1, Sprite2)

collide_circle = pygame.sprite.collide_circle_ratio(1.5)
collide_circle(Sprite1, Sprite2)

Bu şekilde olmasını bu sınıfların __call__ methodu sağlıyor. Nasıl __init__ methodu sınıf başlatılınca çalışıyorsa, __call__ methodu ise bu şekilde çalışıyor…

Burada verilen float değerlere bakarsak 2.0 değeri dikdörtgen alanın iki katına çıakrtır. Eğer -1.0 verirseniz aynı değerde kalır, 0.5 ise yarıya düşürür. Bu oranlara göre istediğiniz gibi Sprite nesnenize görünmez bir alan sağlıyabilirsiniz. Örnek olarak radar alanı verilebilir…

groupcollide fonksiyonu ise iki Sprite grubu nesnesinin çarpışmalarını kontrol ediyor. Ve gerekli parametre verilirse çarpışan grupların elemanlarını sildirebiliyorsunuz…

pygame.sprite.groupcollide(grup1, grup2, True, False)

Parametre olarak iki grup girdik. Üçüncü parametre ile grup1 in elemanları çarpışınca silinecek, dördüncü parametrenin False olmasıyla grup2 nin elemanları silinmeyecektir. Bu fonksiyon ile Kamikaze Saldırısı adında bir oyun yapabilirsiniz :)

Son fonksiyonumuz ise spritecollide(). Bu fonksiyon ile de bir Sprite ın, bir sprite grubuna temas etmesini kontrol ediyoruz.

pygame.sprite.spritecollide(sprite, grup, True)

Bu kod ile sprite a temas eden grup üyeleri True parametresi sayesinde yok olacaktır. Eğer False verirseniz spritecollide() fonksiyonu çarpışan Sprite nesnelerini liste olarak döndürecektir…

pygame.sprite modülünde bulunan bu fonksiyon ve sınıfları öğrenerek Sprite derslerinin sonuna gelmiş olduk. Bundan sonra neler olacağını zaman gösterecek…

Yazım hatası varsa bildiriniz.
Bu yazı Creative Commons-BY-SA ile lisanslanmıştır. Bu yazıyı ilk sahibini belirtmek ve aynı lisansla dağıtmak koşuluyla kullanabilirsiniz.

Benzer Yazılar:

  1. Pygame ile Oyun Programlama – Sprite 1. Bölüm
  2. Pygame ile Oyun Programlama – Sprite 2. Bölüm
  3. Pygame ile Oyun Programlama – Sprite 3. Bölüm
  4. Pygame ile Oyun Programlama – Image Modülü
  5. Pygame ile Oyun Programlama – Font Modülü
15
Ağu

Bu yazıda cx_Freeze modülünü kullanarak Python kodlarımızı nasıl çalıştırılabilir(*.exe, Linuxta uzantı yok) yapacağımızı öğreneceğiz. Bu sayede yazılımlarınızı fazladan Python kurulumu yaptırtmadan dağıtabileceksiniz. Ayrıca ortaya çıkan ürün portable uygulama olarakta kullanılabilir…

Öncelikle GNU/Linux kullanıcıları için bu işin nasıl yapılacağını anlatacağım…

Kullandığınız GNU/Linux dağıtımızın paket depolarında mevcut olması muhtemel bu modülü paket yöneticinizden cx_freeze olarak aratıp kurabilirsiniz(Pardusta adı python-cx_freeze, Ubuntu da cx-freeze).

Derlemek istediğiniz Python projenizin bulunduğu dizine girin ve bir konsol açın. Konsola “cxfreeze dosya_adi.py” komutunu verin. cxfreeze betiği kodlarınızı inceleyip gerekli modülleri tespit eder ve çalıştırılabilir bir dosya oluşturur. Bunu aynı dizinde dist adlı dizinde görebilirsiniz. Eğer projenizle ilgili resim, müzik veya ayar dosyalarınız varsa dağıtacağınız uygulamanıza bu dosyaları ilave edin…

Şimdi ise Windows kullanıcıları için nasıl kod derleneceğine gelelim… Windows kullanıcıları cx_Freeze modülünün Python sürümüne göre olan binary dosyasını indirip kurmaları gerekmektedir.

İşimizi kolaylaştırmak için Gui2exe adlı uygulamayı kullanacağız. Bu sayede görsel olarak setup.py dosyası hazırlayacağız. Gui2exe uygulamasını buradan indirebilirsiniz. Bu uygulama wx adlı gui modülü gerektirdiği için wxPython sitesinden Python sürümünüze göre olanın unicode destekli olanını indirip kurun. Artık Gui2exe uygulamasını çalıştırabiliriz.

Gui2exe yi arşivden çıkarıp GUI2Exe adlı klasöre giriyoruz ve GUI2Exe.py dosyasına çift tıklayıp uygulamayı çalıştırıyoruz…

Açılan ekranda File>New project… yoluna tıklayıp çıkan dialogda OK butonuna basıyoruz. Sol menüde bulunan My Projects in altındaki GUI2Exe Project e çift tıklıyoruz. Sağda açılan kısımdan cx_Freeze ye tıklıyoruz.

Uygulama ekranının ortasında GUI2Exe Project adında bir sekme oluştu. Bu sekmede yer alan grupların ne işe yaradıklarına bakalım…

Target Classes(1):

Exe Kind başlığının altındaki satıra tıklayarak uygulamanızın konsol mu, yoksa guili bir uygulama mı olduğunu seçiyorsunuz.

Python Main Script başlığının altındaki satırın sağ tarafına tıklayarak *.exe ye dönüştüreceğiniz betiğin yolunu giriyorsunuz.

Executable Name kısmına *.exe dosyanızın adını yazıyorsunuz.

Version kısmına uygulamanızın versiyonunu, Description kısmına ise uygulamanızın ne işe yaradığını açıklayan bir yazı yazıyorsunuz.

Author kısmına Uygulamayı geliştirenin adını, Program Name kısmına ise uygulamanızın adını yazıyorsunuz.

Common Options:

Optimize kısmından 0-2 arası bir değer vererek Python kodlarının optimizasyonunu ayarlayabilirsiniz.

Compressed kısmından oluşturulacak *.zip dosyalarının sıkıştırılmasını sağlayabilirsiniz.

Dist Directory kısmını aktif ederek binary dosyaların oluşacağı dizinin adını değiştirebilirsiniz.

Packages grubunda ise sağ alt taraftaki + butonuna tıklayarak Python paketi ekleyebilirsiniz. Örneğin, PyQt veya pygame kullanarak bir uygulama geliştirdiyseniz bu gruptaki liste widgetine bu paketin adını yazmalısınız ki derlemeden sonra çalıştırdığınızda hata almayasınız.

Other Options grubunda ki Icon File kısmından *.exe dosyanızın gözükeceği resmi seçebilirsiniz.

Her şey tamamsa ve bir hata olduğunu düşünmüyorsanız sağ altta bulunan Compile butonuna tıklayarak derleme işlemine başlayabilirsiniz. Derleme başarılı olursa bir dialog çıkacak ve çalıştırmak isteyip istemediğinizi soracak. Başarılı bir derlemeden sonra *.exe ye çevirdiğiniz betiğin bulunduğu dizine girip binary dosyalarınıza ulaşabilirsiniz.

İsterseniz File menüsünden Export setup file… a tıklayarak oluşan setup.py dosyasını kaydedebilirsiniz.

Gui2exe kullanırken Türkçe karakter kullanırsanız derlemede hata verecektir. Türkçe karakter kullanmakta ısrarlıysanız setup.py yi dışarı aktararak dosyanın başına #-*- coding:utf-8 -*- satırını eklemelisiniz.

Aynı setup.py dosyasını GNU/Linux altında da kullanabilirsiniz. Ancak Gui2exe Windows altında çalıştığı için, GNU/Linux da setup.py dosyasını elle oluşturmanız gerekecektir. İsteyenler buradan setup.py dosyasına neler yazılabileceğini öğrenebilirler.

Ek: setup.py dosyasını python setup.py build komutuyla kullanıp binary oluşturabilirsiniz.

Windows kullanıcıları cxfreeze betiğini kullanmak isterlerse, Python’un kurulu olduğu dizinde ki Script dizinine girerek cxfreeze.bat dosyasını kullanabilirler. Bunun için cmd ile o dizine girip cxfreeze.bat dosya_yolu\dosya_adi.py gibi bir komutla aynı GNU/Linuxta ki gibi derleyebilirler. Yalnız gui kullanılan bir uygulamayı derliyorsanız programı çalıştırdığınızda cmd de açılacaktır…

Derleme de sorun yaşayanlar sorunları bildirirse çözmeye çalışırız…

Yazım hatası varsa bildiriniz.
Bu yazı Creative Commons-BY-SA ile lisanslanmıştır. Bu yazıyı ilk sahibini belirtmek ve aynı lisansla dağıtmak koşuluyla kullanabilirsiniz.

Benzer Yazılar:

  1. Python da Kaynak Kodları Gizlemek
7
Ağu

Genelde Python ile kodladığımız bir yazılımı kaynak kodlarıyla paylaşırız. Python öğrenenlerde genellikle açık kaynak ve/veya özgür yazılım olarak kodlarını yayınlarlar. Eğer siz diğer gruba dahilseniz ya da en azından ilk başta kaynak kodlarınızı incelemek isteyenlerden; kötü yazılmış kodlarınızı saklamak isteyenlerdenseniz okumaya devam edin…

Amacı, kaynak kodları kapalı bir yazılım geliştirmek isteyen birisi en basitinden py uzantılı dosyaları derleyerek pyc olarak dağıtabilir ya da py2exe, pyinstaller ve cx_freeze gibi modüllerle çalıştırılabilir binary dosyaya dönüştürebilir.

Bizim amacımız ise masumca :) Amacımız python modüllerimizi ve/veya paketlerimizi tek bir yerde toplamak ve kalabalık yapmamak. Örneğin çalıştıracağımız py uzantılı dosyamızın adı oyun.py olsun ve aynı dizinde “lib” adında bir dizin içinde ise __init__.py, gui.py, ai.py dosyaları olsun. Bu durumda dosya yapımız şöyle olacaktır:

oyun.py
lib/
---- __init__.py
---- ai.py
---- gui.py

lib dizinini zip dosyası haline getireceğiz ve farklı bir isim ve uzantıyla kaydedeceğiz. Sizin bu yöntemi kullandığınızı bilmeyen acemiler kaynak kodlarınızı bulamayacaktır :) Amacım kapalı kaynak yazılım yazmayı özendirmek değil. Şu güne kadar ne kodladıysam hepsini gpl v3 ile lisanslamışımdır.

Konuya dönelim ve bu zipleme işini de zipfile modülü ile yapalım. Bu modülü bilmeyenler daha önce yazdığım yazımı inceleyebilirler.

import zipfile

zip = zipfile.ZipFile('save.data',"w",zipfile.ZIP_DEFLATED)
zip.write("lib/__init__.py")
zip.write("lib/ai.py")
zip.write("lib/gui.py")
zip.close()

lib diziniyle aynı dizinde bu betiği çalıştırırsanız save.data adında bir zip arşivi oluşacaktır. Şimdi bu save.data adlı arşivimizi oyun.py de çağıralım.

import sys

sys.path.insert(0, "save.data")

import lib.ai
from lib import gui

Görüldüğü gibi fazladan iki satır kod yazıp arşiv dosyamızı path e ekledik ve kodları gizlemiş olduk. Siz siz olun kodlarınızı özgür yapın. Sonra bu yazıyı bahane ederek gezegenlerden atılmak istemem :) Sürekli pygame yazısı yazdığım için değişiklik olsun diye bu özelliği anlattım. py2exe ile uygulamanızı çalıştırılabilir yaptıysanız belki dizin içinde zip dosyası görmüşsünüzdür. İşte bu zip dosyası da benim anlattığım gibi kullanılmaktadır.

Eğer modüllerinizde aynı dizin içinde, yahut zip arşivinin içine gelecek şekilde bir dosya okumaya ve/veya yazmaya çalışırsanız hata alırsınız. Pygame ile resim dosyasını göstererek Surface nesnesi oluşturmayı denerseniz hata alırsınız. Benim deneyimlerimden bunlar açığa çıktı. Bu yöntemi kullanacaksanız bunun gibi hata çıkaracak unsurlara dikkat ediniz.

Yazım hatası varsa bildiriniz.
Bu yazı Creative Commons-BY-SA ile lisanslanmıştır. Bu yazıyı ilk sahibini belirtmek ve aynı lisansla dağıtmak koşuluyla kullanabilirsiniz.

Benzer Yazılar:

  1. Python zipfile Modülü

Sprite terimi anlam olarak peri, hayelet vb. anlamına gelse de konu itibariyle alakasız bir anlamı var.

Sprite 2B oyunlarda kullanılan bağımsız görüntülerdir. Bir sprite tekil ya da birden fazla resimden oluşabilir. Bu resimlerin arka arkaya oynamasıyla animasyon oluşur. Pygame de Sprite kullanmak için pygame.sprite modülünün Sprite sınıfı vardır.

Sprite modülü en az bir Surface ve bir Rect nesnesi içermelidir. Varsayılan olarak self.image niteliği bir Surface, self.rect niteliği de bir Rect nesnesini barındırmalıdır.

Sprite modülü bir sınıftır ve bu sınıfı kullanmak için yeni bir sınıf oluşturup miras almalıyız.

from pygame.sprite import Sprite
import pygame

class Kare(Sprite):
    def __init__(self):
        Sprite.__init__(self)
        self.image = pygame.Surface((100,100))
        self.rect = self.image.get_rect()

En basit Sprite sınıfı bu şekildedir. Bu sınıfı şu şekilde kullanabiliriz.

import pygame, sys
from kare import Kare
pygame.init()

pencere = pygame.display.set_mode((500,400))

kare = Kare()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

    pencere.fill((255,255,255))

    pencere.blit(kare.image, kare.rect)
    pygame.display.flip()

Kare sınıfımızı kare.py adıyla kaydettiğimizi varsayarsak yukarıda from kare import Kare ile sınıfımızı çağırmış oluyoruz. kare örneğine Kare sınıfımızı atıyoruz ve ana döngümüzde sınıfımızın self.image niteliğini ve self.rect niteliğini kullanarak ekrana yüzeyimizi çizdiriyoruz.

Sprite sınıfının kullanımı basit ve hızlıdır. Bu hızın nedeni en iyi şekilde optimize edilmesindendir. Çoğu zaman kendi sınıfınızı yazmak yerine Sprite sınıfını miras alarak genişletmeniz yeterlidir.

Sprite ın bir çok avantajı vardır. Genişlettiğiniz sınıfı argüman alacak şekilde ayarlayıp sınıfınızın çeşitli özellikte yüzeyler oluşturmasını sağlayabilirsiniz. Ayrıca Sprite sınıfının methodlarında update() methodu ile oyun döngüsüne yazacağınız onlarca satır kodu bu methoda yazarak döngüde tek satır yer kaplamasını sağlayabilirsiniz. Ve tabii ki update() methoduyla da istediğiniz gibi argüman alabilirsiniz. Sprite sınıfının başka methodları da mevcuttur, ama update() methodu haricindekilerin kullanımına rastlamanız düşük bir ihtimal, ki gerekte yoktur.

Şimdi Kare sınıfımızı geliştirelim:

# kare.py
from pygame.sprite import Sprite

class Kare(Sprite):
    def __init__(self, renk, konum):
        Sprite.__init__(self)
        self.image = pygame.Surface((100,100))
        self.image.fill(renk)
        self.rect = self.image.get_rect()
        self.rect.x, self.rect.y = konum

Kare sınıfımıza renk ve konum adında iki tane parametre ekledik ve renk parametresinin değerini self.image.fill() e atadık. konum adlı parametrenin değerini ise rect nesnemizin x ve y niteliğine atadık. Biz renk parametresinden üç elemanlı bir tuple, konum parametresinden ise iki elamanlı bir tuple bekliyoruz. Bu parametrelere verilecek değerler çizilecek olan karemizin rengini ve konumunu belirleyecek.

Şimdi de yeni Kare sınıfımızı nasıl kullanabileceğimize bakalım:

import pygame, sys
from kare import Kare
pygame.init()

pencere = pygame.display.set_mode((500,400))

renkler_konumlar = [[(255,0,0),(50,50)],
                    [(0,255,0),(150,100)],
                    [(0,0,255),(75,150)]]

kareler = []

for renk, konum in renkler_konumlar:
    kareler.append(Kare(renk,konum))

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

    pencere.fill((255,255,255))

    for kare in kareler:
        pencere.blit(kare.image, kare.rect)

    pygame.display.flip()

renkler_konumlar adında bir liste oluşturduk ve içine 3 liste daha oluşturduk. Bu üç listeye de Kare sınıfımıza gireceğimiz parametreleri girdik. Hemen altında kareler adında boş bir liste oluşturduk. Bu listeye for döngüsü yardımıyla, renkler_konumlar listesinden gelen verilerle oluşturulan Kare sınıflarımızı ekledik. Oyun döngümüzde ise yine bir for döngüsüyle kareler listesindeki Kare nesnelerini ana yüzeyimize çizdirdik. Sonuç olarak birbiriyle bitişik halde; kırmızı, yeşil ve mavi kareler çizdirmiş olduk.

Sprite sınıfının kullanımı bu kadarla bitmiyor; update() methoduyla Kare sınıfımızda yapılan değişiklikleri ekrana yansıtabiliriz. Bu sayede oyun döngümüzde kalabalık yapan onlarca satır kodu update() methodlarında yazabiliriz.

# kare.py
from pygame.sprite import Sprite

class Kare(Sprite):
    def __init__(self, renk, konum):
        Sprite.__init__(self)
        self.image = pygame.Surface((100,100))
        self.image.fill(renk)
        self.rect = self.image.get_rect()
        self.rect.x, self.rect.y = konum

    def update(self):
        if pygame.key.get_pressed()[pygame.K_LEFT]:
            self.rect.x -= 1
        if pygame.key.get_pressed()[pygame.K_RIGHT]:
            self.rect.x += 1
        if pygame.key.get_pressed()[pygame.K_UP]:
            self.rect.y -= 1
        if pygame.key.get_pressed()[pygame.K_DOWN]:
            self.rect.y += 1

update methodumuzda klavye ok tuşlarıyla karemizin yer değiştirmesini sağlıyoruz. Bu kodu Sprite kullanmadan önce oyun döngümüze yazıyorduk. Bu durumda oyun döngümüze update() methodumuzu yazmamız yeterli olacaktır:

import pygame, sys
from kare import Kare
pygame.init()

pencere = pygame.display.set_mode((500,400))

kare = Kare((255,0,0),(50,50))

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

    pencere.fill((255,255,255))

    kare.update()

    pencere.blit(kare.image, kare.rect)
    pygame.display.flip()

Bu kadar basit… Sekiz satırlık kodu update() methodumuza yazdık ve oyun döngümüzde çağırarak tek satır yer kaplamasını sağladık.

Spritelar genellikle animasyon için kullanılır. Sprite animasyon dediğimiz bu terim, ard arda oynatılan resimlerle meydana gelen hareketli yüzeyleri belirtir. İnternette “Sprite sheet” diye aratırsanız 2B oyunlarda kullanılmak üzere çizilmiş yüzlerce; kare kare çizilip, tek yerde toplanmış resim dosyaları bulacaksınız. Bu resimleri kullanarak örneğin; oyunumuzdaki karakterin hareketlerini oluşturabilir ve klavye kontrolleriyle animasyonları gösterebiliriz. Tabii bunu tek resim dosyasından, grafiklerin tek tek dikdörtgen alanını bulup kullanacağınız gibi her kareyi tek bir resim dosyası haline getiripte Sprite animasyonunu oluşturabilirsiniz.

Çok basit bir Sprite animasyonu yapalım ve gelecek derslere motive edici bir etkisi olmasını dileyelim.

# asker.py
from pygame.sprite import Sprite
import pygame

class Asker(Sprite):
    def __init__(self, konum):
        Sprite.__init__(self)
        self.resimler = [pygame.image.load("00.png"), pygame.image.load("01.png")]
        self.image = self.resimler[0]
        self.rect =  self.image.get_rect()
        self.rect.x, self.rect.y = konum
        self.say = 0

    def update(self):
        if pygame.key.get_pressed()[pygame.K_LEFT]:
            if self.say >= 2:
                self.say = 0
            self.rect.x -= 4
            self.image = self.resimler[self.say]
            self.say += 1

        if pygame.key.get_pressed()[pygame.K_RIGHT]:
            if self.say >= 2:
                self.say = 0
            self.rect.x += 4
            self.image = pygame.transform.flip(self.resimler[self.say],1,0)
            self.say += 1

self.resimler adında bir liste oluşturduk ve 00.png ve 01.png resimlerinin Surface halini listeye ekledik. Her Sprite nesnesinde olması gereken self.image niteliğine self.resimler listesinin ilk elemanını atadık. Bu resim karakterin durduğu anı temsil ediyor.

self.say adında da bir sayaç oluşturduk; bunun amacı da self.resimler listesindeki Surface nesnelerini sırayla göstermek içindir.

update() methodumuz da sağ ve sol yönler için sağ ve sol ok tuşlarına basılması durumu için iki adet if bloku açtık. Bu if bloklarında self.rect adındaki rect nesnemizin x niteliğinin değerlerini artırıp, azaltarak sağa ve sola hareketini sağladık. self.image niteliğini; self.say ın tuttuğu sayıyla, self.resimler listesinde o sıraya tekabul eden Surface nesnemizle değiştirdik ve ardından self.say ın değerini bir artırdık. Bu şekilde sağ ve sol ok tuşlarına basılınca self.resimler listesindeki Surface nesneleri akıcı şekilde ekrana çizilecektir. Sprite karelerinin az olması çok hızlı akmasına neden oluyor, ama siz elinizdeki sprite grafiklerinizle çoğaltıp test edebilirsiniz.

Sağ ok tuşuna basıldığında çalışacak kodlara baktığımızda daha önce görmediğimiz pygame.transform.flip() ile karşılaşıyoruz. transform modülünün flip fonksiyonu ile ilk parametresine verdiğimiz Surface nesnemizin ölçeğini x ve y konumunda değiştirebiliyoruz. İkinci parametre ile x ölçeğini, üçüncü parametre ile y ölçeğini değiştiriyoruz. Ben burda x ölçeğine 1 değerini vererek resmin sağ ok tuşuna basılınca x yönünde dönmesini sağladım ve askerimiz de sağa bakmış oldu.

import pygame, sys
from asker import Asker
pygame.init()

pencere = pygame.display.set_mode((500,400))

asker = Asker((250,50))

saat = pygame.time.Clock()
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

    pencere.fill((255,255,255))

    asker.update()

    pencere.blit(asker.image, asker.rect)
    pygame.display.flip()
    saat.tick(24)

asker.py den Asker sınıfını import ettik ve konumunu 250×50 ye ayarladık. Bu sefer Clock nesnesi oluşturduk ve 24 fps olacak şekilde ayarladık. Zaten sprite resimlerin sayısı az olduğu için hızlı akıyordu; bu sayede biraz da olsa hem kısmış olduk, hemde hareket ediş hızını azalttık. Oyun döngümüzde update() methodunu yazdık bu sayede klavye ok tuşlarına bastığımızda kodlarımız çalışacaktır…

Kodların son halini buradan indirebilirsiniz.

Yazım hatası varsa bildiriniz.
Bu yazı Creative Commons-BY-SA ile lisanslanmıştır. Bu yazıyı ilk sahibini belirtmek ve aynı lisansla dağıtmak koşuluyla kullanabilirsiniz.

Benzer Yazılar:

  1. Pygame ile Oyun Programlama – Surface Modülü
  2. Pygame ile Oyun Programlama – Image Modülü
  3. Pygame ile Oyun Programlama – Draw Modülü
  4. Pygame ile Oyun Programlama – Time Modülü
  5. Pygame ile Oyun Programlama – Rect Modülü