Mavi Düşler


Özgürlükiçin’in tema bölümüne yeni özellikler eklene dursun bende orada yapılan çalışmalara heves edip azıcık görünüm ayarlarıyla oynamaya başladım. Normalde masaüstümü olabildiğince sade tutarım, malum işletim sistemini kullanırken ne kadar sade o kadar hızlı mantığı ya da bilgisayarcı büyüklerimin “bilgisayarcı dediğin sade olur” desturuyla olsa gerek hep klasik takılırdım. Bu kötü bir alışkanlıktı; tamam eski sistemlerde klasik takılıyorsun da öyle bir alışıyor ki insan artık süper bilgisayarlarla karşılaştığında bile önce sistemi sadeleştiriyorum.

Klasik tema, klasik menüler ve diğer sıkıntılardan sonra Pardus 2009’umuz ile birlikte ekranımızı şenlendirmeye karar verdik. Blend temasının arka planına güzel mas mavi bir resmi döşedik. Panelin boyutunu küçültebildiğimi bilmiyordum! O da iyi oldu^^ Son olarak sistem ayarlarında renklere baktım ve temaya uygun mavili bir paleti seçtim, harika oldu. En çok sevdiğim yanı bilgisayarı kapatırken karşımıza çıkan seçeneklerin tasarımı. Tuşlar parlıyor 🙂 Neyse şöyle bir ekran görüntüsü ekleyelim de herkes mavi düşlere dalsın!

Oyun Yapımı -3

Vakit bol olunca uğraşıp duruyoruz. Bundan böyle kodlar uzadığı için google code üzerinde oluşturduğum bir proje üzerinden sizlere dosyaları ulaştıracağım. Oyunumuzun adı gmsgame oldu ve bundan böyle gplv3 ile lisanslı. 0.3 numaralı versiyon şu adresten indirilebilir. Şimdi gelelim bu versiyonla birlikte neler yaptığımıza. Öncelikle artık girdiğimiz verileri bir veritabanında tutuyoruz. Veritabanı olarak Sqlite’ı tercih ettim, kullanım gayet basit ve Pardus 2009’da Python bağlantıları kurulu geliyor.

İlk açtığımızda dosya ile aynı dizinde test.db isimli bir dosyayı okumaya çalışıyoruz. Dosya yoksa ya da silmişseniz tekrardan bir karakter oluşturuyoruz. Bundan böyle veritabanına sahip olduğumuz için her açtığımızda karakter bilgilerini girmekle uğraşmayacağız ve direkt aksiyona dalacağız. Sadece yaratıklar değişecek ve farklı sonuçlar olacak. İkinci yazıda gözden kaçırdığım bir “break” ifadesi yüzünden bizde savaşın sonunda ölüyorduk. Bu hatayı giderdim. Örnek olması açısından geliştirmeye devam edeceğim bu sayede bende bilgilerimi güncelliyorum, veritabanı ile uğraşmayalı çok olmuştu iyi oldu 🙂

Düzeltme: Dosyayı yanlışlıkla sildim, eski versiyon üzerinde çalıştığım için eski kodları ve dosyayı yapıştırmam imkansız. Bir sonraki versiyona bakın.

Oyun Yapımı -2

Gece yazdığım uygulamaya sabah ek yapıyorum. Şimdi dediğim gibi rastgele çekebilirdik canavarı bende öyle yaptım ama sadece sağlığını değiştirdim. Saldırı puanını bir sonraki yazıda düzenlerim. Rastgele seçim yapmak için önce canavarlar isimli bir sözlük nesnesi oluşturdum sonra random modülünün choice() fonksiyonunu kullanarak bu sözlüğün anahtarlarından rastgele bir seçim yaptım. Aşağıda ki while döngüsüne tekrardan bir ek yapma gereği duydum sorun şuydu eğer canavarın canı 3’e iner ve bundan saldırı puanımız yüksekse negatif olarak işlem devam ediyor ve sonunda ölüyorduk. Buraya bir ek yapıp canavarın canı güçten ufak olduğundan değerini otomatik sıfır yapıyoruz ve biz kazanıyoruz. Ayrıca while döngüsünün başına tekrardan bir koşul koydum. Oyuncu canını 0 olarak işaretlerse oyuna başlamadan kaybedecek.



#!/usr/bin/env python

# -*- coding: utf-8 -*-

import random


print "Karakter yaratım işlemi başlamak üzere lütfen hazırlanın gireceğiniz değerlerin toplamı 20 olmalı"

zeka = raw_input("Zeka puanı: ")

guc = raw_input("Güç puanı: ")

karizma = raw_input("Karizma puanı: ")

ceviklik = raw_input("Çeviklik puanı: ")

can = raw_input("Can puanı: ")

toplam = int(zeka)+int(guc)+int(karizma)+int(ceviklik)+int(can)


if toplam == 20:

  print "işlem başarılı."

  canavarlar = {"kutupayisi":"50","demon":"30","bildircin":"20","solucan":"5"}

  sans = random.choice(canavarlar.keys())

  canavar = canavarlar[sans]

  sal = 2

  saglik = int(can) * 5


  print "deneme savaşı başlatılıyor..."

  if saglik == 0:

    print "Tebrikler başlamadan kaybettiniz"

  else:

    while saglik > 0:

      saglik = int(saglik) - int(sal)

      print "canınız %s'e indi" % saglik

      canavar = int(canavar) - int(guc)

      print "canavarın canı %s'e indi" % canavar

      if saglik == 0:

	print "öldünüz ühühü"

	break

      elif canavar == 0:

	print "kazandınız ohh yeahhh"

	break

      elif canavar

Oyun Yapımı -1

Arada sırada Python bilgimi tazelemek için boş işlerle uğraşırım. Bu da uğraştığım boş işlerden birisi. Oyun programlamaya girdiğinizde tüm oyunların birer döngüden ibaret olduğunu göreceksiniz. En basitinden tutunda en karmaşık oyunlara kadar hepsi döngüler üzerine kuruludur. Zaten çoğunda Panda3d yazılarında bahsettiğim gibi loop() fonksiyonu gibi fonksiyonlar kullanırsınız. Hazır bir oyun motoru kullanırsanız bu fonksiyonlar önceden tanımlanmış olur, kullanmazsanız da verdiğim örnekteki gibi döngüleri kendiniz hazırlamak zorundasınız.

Örnekte önce kullanıcıdan karakteri için bazı bilgiler isteniyor. İki tanesini kullanmış olduk. Sonra aldığımız bu değerleri işleyip hazırladığımız rakip değerler ile işleme tabi tutuyoruz. Mesela burada canavar diye bir nesne oluşturdum. Bu ileride şöyle geniş bir tüp içinde belli sayıda nesne olabilir ve bu nesneler içerisinden karakter karşısına rastgele bir rakip çıkarabiliriz. Neyse yaptığımız işlem toplama ve çıkarmadan ibaret while döngüsüyle ölene kadar çıkartma yapıyoruz eğer rakiplerden birisinin canı sıfıra inerse işlemi kesip sonucu bildiriyoruz.


#!/usr/bin/env python
# -*- coding: utf-8 -*-

print "Karakter yaratım işlemi başlamak üzere, gireceğiniz değerlerin toplamı 20 olmalı"
zeka = raw_input("Zeka puanı: ")
guc = raw_input("Güç puanı: ")
karizma = raw_input("Karizma puanı: ")
ceviklik = raw_input("Çeviklik puanı: ")
can = raw_input("Can puanı: ")
toplam = int(zeka)+int(guc)+int(karizma)+int(ceviklik)+int(can)

if toplam == 20:
print "işlem başarılı."
canavar = 20
sal = 2
saglik = int(can) * 5

print "deneme savaşı başlatılıyor..."
while saglik > 0:
  saglik = int(saglik) - int(sal)
  print "canınız %s'e indi" % saglik
  canavar = int(canavar) - int(guc)
  print "canavarın canı %s'e indi" % canavar
  if saglik == 0:
    print "öldünüz ühühü"
    break
  elif canavar == 0:
    print "kazandınız ohh yeahhh"
    break
  else:
    continue

else:
print "işlem başarısız."

Panda3D Hareket İçin Interval

Evet arkadaşlar, sahnemizi oluşturduk. İçerisine bir panda koyduk güzel oldu şimdi sırada pandamızı hareket ettirmeye geldi. Bunun için Interval denilen bir özelliği kullanacağız. Öncelikle kodlarımızı ekleyelim:


import direct.directbase.DirectStart
from pandac.PandaModules import *

from direct.task import Task
from direct.actor import Actor
from direct.interval.IntervalGlobal import *
import math

environ = loader.loadModel("models/environment")
environ.reparentTo(render)
environ.setScale(0.25,0.25,0.25)
environ.setPos(-8,42,0)

def SpinCameraTask(task):
angledegrees = task.time * 6.0
angleradians = angledegrees * (math.pi / 180.0)
base.camera.setPos(20*math.sin(angleradians),-20.0*math.cos(angleradians),3)
base.camera.setHpr(angledegrees, 0, 0)
return Task.cont

taskMgr.add(SpinCameraTask, "SpinCameraTask")

pandaActor = Actor.Actor("models/panda-model",{"walk":"models/panda-walk4"})
pandaActor.setScale(0.005,0.005,0.005)
pandaActor.reparentTo(render)
pandaActor.loop("walk")

pandaPosInterval1= pandaActor.posInterval(13,Point3(0,-10,0), startPos=Point3(0,10,0))
pandaPosInterval2= pandaActor.posInterval(13,Point3(0,10,0), startPos=Point3(0,-10,0))
pandaHprInterval1= pandaActor.hprInterval(3,Point3(180,0,0), startHpr=Point3(0,0,0))
pandaHprInterval2= pandaActor.hprInterval(3,Point3(0,0,0), startHpr=Point3(180,0,0))

pandaPace = Sequence(pandaPosInterval1, pandaHprInterval1,
pandaPosInterval2, pandaHprInterval2, name = "pandaPace")
pandaPace.loop()

run()

Şimdi interval nedir onu açıklayalım. Öncelikle bir tür zamanlanmış görev olduğunu söylesek yanlış olmaz. Belli bir zaman aralığında bir değeri başka bir değere çeviririz. Eklediğimiz satırlara bakacak olursanız ilk olarak pandaPosInterval1 isimli bir nesne oluşturduğumuzu görürsünüz, bu nesnelerin isimleri o kadar da önemli değil ama ben ana dokümana sağdık kalıyorum aynı zamanda ne olduklarını açıklayan birer cümle gibi kullanıldıkları için ileride hatırlamanıza yardımcı olur. Neyse, nesnemizi oluşturduk ve posInterval fonksiyonunu kullandık fonksiyonda belirttiğimiz üzere başlangıç pozisyonu 0,10,0 noktası. Bu noktadan 13 saniyelik bir zaman içerisinde 0,-10,0 noktasına geçmiş oluyoruz. Sonraki satırdaysa aynı şeyi tersten yapıyoruz. Hpr ise anladığınız üzere açıyı değiştiriyor.

Son kısımda ise başka bir görev türüne geçiyoruz. Sequence sırayla Interval’ları gerçekleştiren bir görev türü. Sıraladıktan sonra loop() fonksiyonunu kullanarak bir döngü oluşturmuş oluyoruz. Zaten her şey döngüden ibaret…

Bu yazıyla birlikte Panda3D’yi sizlere tanıtmak için başlattığım seriyi bitirmiş oldum. Bundan sonra insanlara Panda’yı öğretmeye çalışmaktan ziyade tecrübelerimi paylaşacağım yazılar gelebilir. Panda3D ile uğraşan, animasyon yapan, kendini geliştirmek isteyenler benimle iletişim bölümü aracılığıyla irtibata geçebilir. Umarım bende sizlerden bir şeyler öğrenebilirim.

İyi Çalışmalar
Ceyhun Alyeşil

Panda3D Aktörler

import direct.directbase.DirectStart
from direct.task import Task
from direct.actor import Actor
import math

environ = loader.loadModel("models/environment")
environ.reparentTo(render)
environ.setScale(0.25,0.25,0.25)
environ.setPos(-8,42,0)

def SpinCameraTask(task):
angledegrees = task.time * 6.0
angleradians = angledegrees * (math.pi / 180.0)
base.camera.setPos(20*math.sin(angleradians),-20.0*math.cos(angleradians),3)
base.camera.setHpr(angledegrees, 0, 0)
return Task.cont

taskMgr.add(SpinCameraTask, "SpinCameraTask")

pandaActor = Actor.Actor("models/panda-model",{"walk":"models/panda-walk4"})
pandaActor.setScale(0.005,0.005,0.005)
pandaActor.reparentTo(render)
pandaActor.loop("walk")

run()

Sahnemizi daha önce ki eğitsellerde yüklemiştik. Kodumuz gittikçe gelişiyor şimdi ilk olarak import ettiğimiz modüllere tekrardan bakın. Ekstradan Actor modülünü import ettik. Şimdi uygulamanın son bölümüne bakın, tıpkı sahne yüklerken yaptığımız gibi bir nesne oluşturduk ve Actor.Actor fonksiyonuyla pandamızı yükledik. Şimdi aklınızda tutmanız gereken kısım loadmodel’in sabit modelleri yüklemede, Actor’ınsa hareketli animasyonlarda kullanıldığı. Bir şey hareket ediyorsa yani yeri değişiyorsa actor kullanılır. Actörü yüklerken bir python sözlüğü kullanarak dosyalarımızı isimlerle eşleştirebiliyoruz. Örneğin walk nesnesinin adresi models/panda-walk4’muş. Yerini belirleyip, render işlemini yaptıktan sonra walk animasyonunu loop ediyoruz(döngü başlatıyoruz). İşlem tamamlandıktan sonra dosyayı kaydedip çalıştırın. Yukarıda ki resimdeki pandanın yürüdüğünü göreceksiniz.

Panda3D Kamera Kontrolü

Devam ediyoruz, şimdi aşağıdaki kodları inceleyelim:

import direct.directbase.DirectStart
from direct.task import Task
import math

environ = loader.loadModel("models/environment")
environ.reparentTo(render)
environ.setScale(0.25,0.25,0.25)
environ.setPos(-8,42,0)

def SpinCameraTask(task):
angledegrees = task.time * 6.0
angleradians = angledegrees * (math.pi / 180.0)
base.camera.setPos(20*math.sin(angleradians),-20.0*math.cos(angleradians),3)
base.camera.setHpr(angledegrees, 0, 0)
return Task.cont

taskMgr.add(SpinCameraTask, "SpinCameraTask")

run()

Yine DirectStart’ı import ettik fakat bu sefer ekstra bir kaç modülü daha kullanmamız gerekti. Geçen sefer eklemiş olduğumuz sahnemizde kamera düzgün değildi burada işi halletmesi için SpinCameraTask isimli bir fonksiyon yazdık. Panda3D’nin görev yöneticisine taskMgr.add komutuyla yazdığımız görevi ekledik. Bu sayede görev yöneticisi SpinCameraTask’ı Task.cont’a döndüğü sürece uygulayacak(Task.done olduğunda bitiriyor, burada kullanmadık). Kamerayı döndürmeye yarayan fonksiyona bakacak olursak Task.time task’ın süresini belirtir biz burada saniyede 6 derece dönmesini istiyoruz. Sonraki satırda dereceden radyanı buluyoruz. setPos ile pozisyonunu belirtip(trigonometri, analitik geometri dediğim burada giriyor x,y,z koordinatları, yerden 3 birim yüksekte oluyor)setHpr ile de dönüşümü ayarlıyoruz(bunlar base.camera ile ilgili şimdilik buraya takılmayın).
Kodu çalıştırdığınızda kameranın artık bozuk olmadığını ve döndüğünü göreceksiniz.

Panda3D Sahne Yükleme


import direct.directbase.DirectStart

environ = loader.loadModel(“models/environment”)
environ.reparentTo(render)
environ.setScale(0.25,0.25,0.25)
environ.setPos(-8,42,0)

run()

Yine önce DirectStart’ı import ediyoruz. environ isimli bir nesne oluşturduk bu nesnemize modelimizi yükledik. “models/environment” kısmının ayrıntılı kullanımı için dosya söz dizimi eğitseline bakabilirsiniz. Aslında pygame dokümanlarını okumuş olan arkadaşlar sistemin benzer olduğunu fark edecektir. Nesneleri yükleyip render ediyoruz sonrada oynatıyoruz. Nesnelerin açı ve pozisyon değerlerini belirliyoruz. Ayarlanabilen bir çok özellik mevcut ileride bunlara da örnek gösteririm. Açılar, pozisyonlar değişir ama bu bölümde dikkat etmeniz gereken iki komut loadModel ve reparentTo, bunları her zaman kullanacağız. Bir hata yapmamışsak dosyamızı çalıştırdığımızda şunları görmemiz gerekecek^^

Panda3D Başlangıç

Öncelikle düzgün kurulup kurulmadığına bakalım:

import direct.directbase.DirectStart
run()

Satırlarını boş bir belgeye yazalım ve uzantısını .py yaparak kaydedelim. DirectStart vasıtasıyla gerekli bazı modülleri yükledik. Run komutuyla da döngümüzü başlattık. Her oyunda bir tane run() komutu uygulanır oyunumuzu başlatan bu komuttur bu yüzden bu boş dosyada da onu kullandık. Bu komut her zaman son satıra yazılır bunu unutmayın. Dosyamızı deneme.py ismiyle kaydettiğimizi varsayalım. Çalıştırmak için konsola python deneme.py yazın, karşınıza boş bir pencere gelecektir.