osa1 github about atom

Pygame ve düzensiz sprite sheetlerle çalışmak

September 8, 2011 - Tagged as: pygame, python, tr.

Pazartesi günü başlayacak Pyweek’e katılacağım, benim ilk oyunum olacağından daha en temel problemler bile benim için yeni, ve çözümlerini yavaş yavaş keşfediyorum. Birkaç gündür basit oyunlar yapıyorum ve iş bir yerden sonra animasyonlara geldi.

2d oyunlarla ilgilendiyseniz, animasyonların aslında sprite adı verilen png/gif/vs. dosyalarından oluştuğunu bilirsiniz. Animasyonlar çoğu zaman(AAA oyunladan bahsetmiyoruz tabii ki) birkaç kareden oluşuyor ve bunlar genelde tek bir dosyaya aralıklarla yerleştirilmiş oluyorlar. Bunlara sprite sheet deniyor. Örneğin bir karakter koşuyorsa, ilk kare, yukarıdan 100, soldan 50. pixelden itibaren, 40px yüksekliğinde ve 30px genişliğinde oluyor. Bir sonraki kare onun biraz yanında vs. Bu şekilde çalışmak gayet kolay oluyor. Bir kere büyük resmi yükledikten sonra, ondan subsurfacelar oluşturuyorsunuz. Peki neden ayrı ayrı resimler değil? Bunun hakkında iki güzel kaynak: 1, 2.

Çizim işinden hiç anlamadığımdan, sprite sheetleri genelde deviantart’dan ediniyorum. Fakat şu ana kadar basit bir şekilde kullanılabilir bir sprite sheet görmedim. Sprite sheetleri basitce ayrıştırmak için en azından spriteların resim üzerinde eşit aralıklarla falan bölünmesi lazım. Benim bulduklarımın hiçbiri bu şekilde değil. Ne eşit aralıklılar, ne de eşit boyutlu. Tüm kareleri tespit edebilmek için, ya elle ölçecektim, ya da benim için ölçecek bir program yazacaktım :) .

Tabii ki program yazdım. Aşağıda nasıl çalıştığının bir örneğini görebilirsiniz. Gösterdiğim sprite sheet’i tarayıp, birbirlerinden ayrılmış tüm parçaları bulup işaretliyor, mouse ile üzerine geldiğinizde, koordinatlarını ve boyutlarını yazıyor. Bunu sadece Pygame kullanarak yapıyor.(büyültmek için üzerine tıklayın)

Biraz da işin en zevkli kısmından, problemin çözümünden ve algoritmadan bahsedeyim. Program şu şekilde çalışıyor:

Her bir pixel için, eğer pixel colorkey’e eşit değilse(colorkey saydam olacak kısmın rengi ve derinliği oluyor), pixelin içinde olduğu veya komşu olduğu grubu ara. Burda grup bir pygame.Rect. Yani dikdörtgensel bir alan. Eğer bu pixeli içeren bir grup yoksa, bu pixeli içeren en küçük Rect’i gruplara ekle. Eğer piksel Rect’in içindeyse, birşey yapma, komşuysa, Rect’i o pixeli kapsayacak şekilde büyült. Eğer bir pixel birden fazla gruba komşuysa(veya içindeyse), bu iki grubu birleştir. Grupların son hali de ekran görüntülerinde gördüğünüz kırmızı alanlar. Aşağıda bir de Travis Touchdown(No More Heroes’dan) sprite sheeti üzerinde çalışmasını görebilirsiniz.

Böyle işte. Scripti şurdan görebilirsiniz. Konuyla alakalı her türlü algoritma öneri/tavsiye/eleştirisine açığım. Hatta mutlu olurum yani, acımasızca eleştirin lütfen :) .