Forum: Diğer Konular RSS
XNA ve Pacman Çalışmalarım
Sayfa:  1  2  sonraki 
erdem (Moderatör) #1
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: XNA ve Pacman Çalışmalarım
Daha önce bu forumda bir yerlerde bahsettiğim gibi Pacman projemi Microsoft'un XNA oyun geliştirme kütüphanesi üzerine taşıdım.

Bundaki amacım burda edindiğim oyun geliştirme mantığını daha sonra açık kaynak kütüphanelere SDL ya da Clanlib gibi taşımak. İşte bir kaç ekran görüntüsü:

[Resim: http://img44.imageshack.us/img44/46/pac1.jpg]

Burda yaptıklarım:
- Pacman'in klavyeden kontrolü ve hareketli oyun nesnesi (animated sprite) haline getirmek.
Resimden belki belli olmuyor ama klavyede sağa, sola,aşağı yukarı bastığınızda pacman hareketli bir oyun nesnesi haline geliyor. Yukarı aşağı giden pacman resmi oluşuyor.
-Basit bir harita sistemi.
Burada görülen duvarlar, bonuslar ve noktalar bir harita dosyasında saklanıyor. Ve oyun içinde bu harita dosyasından yükleniyor.
- Çarpışma algılaması
Bu kısmı yaparken dikdörtgen cisimler için kullanılan çarpışma algılamasını (rectangle collision) kullandım.

[Resim: http://img22.imageshack.us/img22/3842/pac2x.jpg]


Yapmayı planladıklarım:

- Oyun içi sesler
- Pacman'in düşmanları (hayaletler)
- Yapay zeka
Aslında oyunun orjinal versiyonunda bulunan 4 hayaletin farklı renk, isim ve karakterleri varmış. Pembe olan Speedy, takma ismi "Pinky" ve hızlı. Kırmızı hayaletin ismi Shadow takma ismi "Blinky" her zaman arkanızda ve başınızdan atmak zor. Açık mavi hayalet Bashful takma ismi "Inky" çok ürkek ve sizi görünce kaçmak isteyecek. Portakal rengi hayalet Pokey takma ismi "Clyde", sizi yakalamak için elinden geleni yapacak ama yavaş.
Böyle bir yapay zeka sistemini yapmak zor olacağı için olmazsa sürekli sağa git gibi bir mantıkla çalışan bir yöntem de kullanabilirim.
Bu mesaj erdem tarafından değiştirildi; zaman: 2009-09-18, 00:34.
Avatar
esatarslan52 (Moderatör) #2
Üye Haz 2009 tarihinden beri · 142 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Daha önce c++ ile konsolda çakma bir packman denemem olmuştu(yarım bırakmıştım  :-/ ). Onda kullandığım yapay zeka aşağıdaki şekilde idi. "if (sayac % 20000 == 0)" hızını ayarlamak için. Yeni öğrendiğim daha güzel bir çözümse "if (rand() % 4 == 0)" gibi olanı. Bu sayede level atladıkça  mod değeri 1 azaltılarak dusman git gide daha de zeki hale getirilebilir. Bunu en yakın zamanda D ile yazmaya başlayacağım diziler ve gotoxy() ile uğraşmamın sebebi bunun için. kbhit() için çözüm bulabilmiş değilim.
void Dusman::ilerle(Kahraman *pKahraman)
{
    int dusmanX = getX();
    int dusmanY = getY();
    sayac++;
 
    if (sayac % 20000 == 0)
    {
        sil();
        if (pKahraman->getX()>dusmanX)
            dusmanX++;
        else if(pKahraman->getX()<dusmanX)
            dusmanX--;
 
        if (pKahraman->getY()>dusmanY)
            dusmanY++;
        else if (pKahraman->getY()<dusmanY)
            dusmanY--;
 
        sayac = 0;
    }
 
    setXY(dusmanX,dusmanY);
    ciz();
}
erdem (Moderatör) #3
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Buradan çok fazla bir şey anlamam mümkün değil ama kaynak kodlarını gönderirsen deneyebilirim.. Burada hayaletler o boş olan 4'lü kısımdan çıkacak. Daha sonra oradan rastgele bir yöne ilerleyerek Pacman'i kovalayacaklar. Şimdilik C#'a yabancı olduğum için bir sınıfın bir yapıya erişimi nasıl olur onu anlamaya çalışıyorum. Bunun için de şimdilik static koydum yeterli oldu. Bir de ikinci resimde pacman olduğu noktadan alt, üst, sağ, sol kontrol edecek. Eğer duvarsa hareket etmeyecek değilse hareket edecek. Şimdilik en zor kısım burası gibi.. Haritayı da bir string listede
List<string> harita
olarak tutuyorum. Kullandığım harita da şu şekilde:

111111111111111
133333111333331
131313313313131
121311313113121
131331313133131
131133333331131
133331101133331
131131000131131
131331111133131
1333111x1113331
131313333313131
121333131333121
131101131131131
133333333333331
111111111111111

Burada 1'ler duvarları 0'lar boş alanları 2'ler bonusları 3'ler de pilleri gösteriyor. Ben pacman'i çizen işlevle diğer tüm hareketsiz cisimleri çizen işlevi birbirinden ayırdım. Yoksa yukarıdaki gibi (aslında burada bir x yok) pacman için de haritada bir değer mi gösterseydim emin değilim. Şimdilik List<string>'den yatay :

1333111x1113331

ve dikey

111113001x33331

satırlarını alıp bunları da geçici bir string değişkene atıp bahsettiğim sağ, sol, üst, alt yönlere hareket edebiliyormu kontrolünü yapmayı düşünüyorum.
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Oh oh... Ne güzel şeyler yapıyorsunuz. :)

Ben de kenardan dinleyerek, oyun programcılığından bir şeyler kapmaya başladım. ;)

Ali
Avatar
esatarslan52 (Moderatör) #5
Üye Haz 2009 tarihinden beri · 142 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Kaynak kodu buraya koydum. Kahramanımız için duvar kontrolü var,  düşman için duvar kontrolünü yazmaya çalışırken bırakmışım.
Kahramanımız w-a-s-d tuşları ile hareket eder.

Yeni öğrendiğim daha güzel bir çözümse "if (rand() % 4 == 0)" gibi olanı.

Bunu şurdan öğrenmiştim. Sende bir bak istersen.
erdem (Moderatör) #6
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Aslında bende daha güzel bir kitap var da. Okuması uzun ve konular oldukça ağır ve 100 binlerce satır koddan oluştuğu için henüz bitirmedim. Programming Game AI By Example

Gene de oradaki AI tekniklerine bakarım.

Yalnız senin hangi kütüphaneyi kullandığını anlayamadım. gotoxy ve setxy falan var. Bunları kullanabilmek için hangi kütüphaneyi kullanmam gerekiyor?

@acehreli: Bu arada Ali bey sizin de deneyiminizden yararlanalım :) Diyelim ki üstteki gibi bir haritayı tutmak için en uygun veri yapısı hangisi olabilir. Ben list<string> kullandım ama. Bu arada C#'da map veri yapısı yok diye biliyorum.

Bir de şöyle bir örnekte

131331111133131
1333111x1113331
131313333313131

verileri şu şekilde karşılaştırabileceğimiz bir yapı olabilir mi? Olursa nasıl olur?

Örneğin harita [7][9] == '1' gibi..

Benim kafam biraz bulanık olduğu için böyle bir erişim yöntemi şimdilik aklıma gelmedi. Ama böyle olsa çok kolaylık olacak.
Avatar
esatarslan52 (Moderatör) #7
Üye Haz 2009 tarihinden beri · 142 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
erdem:
Yalnız senin hangi kütüphaneyi kullandığını anlayamadım. gotoxy ve setxy falan var. Bunları kullanabilmek için hangi kütüphaneyi kullanmam gerekiyor?

Harici bir kütüphane kullanmadım. gotoxy ve setxy benim oluşturduğum temel.h ve temel.cpp dosyalarında. Yalnız kodu windows'da yazmıştım. O yüzden gotoxy() winapi leri kullanarak oluşturulmuştur. Başka işetim sistemlerinde hata verir.
acehreli (Moderatör) #8
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
O iki boyutlu bir dizi değil mi? C++'da olsa:

enum HaritaKaresi { bos, duvar, bonus, pil };
typedef vector<HaritaKaresi> Satir;
typedef vector<Satir> Harita;
// ...
Harita harita = /* ... */
harita[satir][sutun] = duvar;

D'de:

import std.stdio;
 
enum HaritaKaresi { boş, duvar, bonus, pil }
 
void main()
{
    HaritaKaresi[5] ilkSatır = HaritaKaresi.duvar;
    HaritaKaresi[5][5] harita;
    harita[] = ilkSatır;
 
    harita[2][2] = HaritaKaresi.pil;
 
    foreach(satır; harita) {
        foreach(kare; satır) {
            write(kare);
        }
        writeln();
    }
}

C#'ta sıralı olması gerekmeyen topluluklar için HashTable varmış; C++'daki map'in eşdeğeri olan da NameValueCollection'mış. Ve tabii ki hiç kullanmadım... :)

Ali
erdem (Moderatör) #9
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Tamam ikinize de çok teşekkürler! :) Şimdilik kafam biraz dağınık olduğu için en kısa zamanda verdiğiniz örnekleri inceleyeceğim.

Bu arada C++'nin gözünü sevem :) D yöntemi de gayet açık gözüküyor.
erdem (Moderatör) #10
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Pacman'den çarpışma algılaması sistemi yapıldıktan sonra yeni bir ekran görüntüsü. Burada dikdörtgensel (rectangular) çarpışma algılaması kullandım.

[Resim: http://img30.imageshack.us/img30/1323/pacmancarpisma.jpg]

Burada kırmızı kısımlar pacman'in geçemeyeceği dikdörtgensel yapılar.
acehreli (Moderatör) #11
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Çok güzel... :) Harita konusunu nasıl hallettin?

Ali
erdem (Moderatör) #12
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Harita yapmadım :) Bunun yerine duvarlar için dikdörtgenler oluşturdum. Bu dikdörtgenler, dikdörtgenin X ve Y koordinatı ile dikdörtgenin genişliğini ve yüksekliğini tutan yapılar:
duvarlar[0] = new Rectangle (xkoordinati, ykoordinati, genislik, yukseklik);
gibi .. Daha sonra pacman aslında dairesel bir cisim ama karşılaştırmak için bir tane de pacmanin etrafında gecici bir dikdörtgensel cisim oluşturdum ve bu mantıkla çarpışma algılamasını yaptım.

Tabi bu biraz yorucu oldu :) Çünkü bu dikdörtgenlerin koordinatlarını teker teker oluşturmak zorunda kaldım.

Aslında bu tür (maze) oyunlarda bir harita sistemi ve bu haritaya dayanan bir çarpışma algılaması yapmak daha mantıklı sanırım. Ama mantığı tam anlamadığım için ve bu yöntem biraz zor geldiği için şimdilik üstteki yöntemle yaptım. Daha sonra bu konuyu da öğrenek pacman'i  harita tabanlı hareket edecek, çarpışma algılamasını da bu sistem üzerinde kuracak şekilde değiştirmeyi düşünüyorum.

Bir de şunu öğrendim. Aslında C#'da çok boyutlu dizi oluşturmak çok kolaymış. Örneğin iki boyutlu bir diziyi:
int[,] benimDizim = new int[4,2];
ya da üç boyutlu bir diziyi
int[,,] benimDizim = new int[4,2,3];
şeklinde oluşturabiliyormuşuz.
acehreli (Moderatör) #13
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Dikdörtgenler işe yaradıysa kalabilirler de, bence onları da haritadan oluşturabilirsin. Haritanın içeriği dikdörtgenlere dönüştürülebilir; çünkü her bir noktası bir bloğu temsil edebilir.

Sonra iç içe iki for döngüsü ile duvarlar'ı oluşturabilirsin.

Ali
erdem (Moderatör) #14
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Güzel bir fikir :) ! Böylelikle diğer bölümler için uğraşmaktan kurtulurum.

Oyunu harita kullanacak şekilde yapmadım çünkü Pacman'in hareket şeklini değiştirmem gerekiyordu. Şimdiki haliyle direkt bir hareketEt() diye bir işlev var. Eğer ızgara tabanlı hareket yapsaydım ilkönce hareketEtmeyeCalis () ve hareketEt () diye iki tane işlev yazmam gerekecekti. Kısacası pacman'in hareket sistemini tamamen değiştirmem gerekecekti.

Ama dediğiniz şekilde olunca hareket şeklini de değiştirmeden harita kullanmak mümkün oluyor. Denedikten sonra buraya tekrar yazarım..
erdem (Moderatör) #15
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Pacman Çarpışma Algılaması

Burada Pacman'in noktaları ve diğer cisimleri yeme davranışını yaptım. Pacman'in etrafında gezen o kırmızı dikdörtgen çarpışma kutucuğu. İlk yapmaya çalıştığımda aynı anda birden fazla nokta yiyebiliyordu. Bunu çarpışma kutucuğunu yarıya indirerek ve konumunu tam merkezde olacak şekilde ayarlayarak düzelttim. Pacman sağa sola hareket etmek istediğinde o kutucuk da hareket yönüne göre bir tarafa kayıyor.

Üst tarafta bulunan şey de hayalet protipi :)
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Sayfa:  1  2  sonraki 
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-18, 09:34:38 (UTC -08:00)