Pygame Animasyon Oluşturma

Pygame’de animasyon oluşturmanıza yardım edecek bir modül oluşturdum. Kodları şudur:

# pygame_animation
from timeit import default_timer as timer
from os import listdir
from os.path import join
import pygame

__all__ = ("init","Animation","update","from_folder")

animasyonlar = []

def init(display):
    global dis
    dis = display

class Animation:
    def __init__(self,images : list,time_interval : float, loop = True):
        assert type(images) == list , "<images> parametresi <list> olmalıdır, <{}> değil.".format(type(images))
        assert type(time_interval) == float , "<time_interval> parametresi <float> olmalıdır, <{}> değil.".format(type(time_interval))
        self.images = images
        self.time_interval = time_interval
        self.pos = [0,0]
        self.is_running = False
        self.loop = loop
    
    def __call__(self):
        """Animasyonu başlatır."""
        self.start()

    def stop(self):
        """Animasyonun durdurur."""
        animasyonlar.remove(self)
        self.is_running = False

    def start(self):
        """Animasyonu başlatır."""
        animasyonlar.append(self)
        self.time = timer()
        self.is_running = True
    
    def jump(self,index=0):
        """Animasyona <index> sırasındaki resimden devam eder."""
        self.time = timer() - self.time_interval*index

    def set_pos(self,*,x=None,y=None):
        """Animasyonun çizileceği konumu değiştirir."""
        if x!=None:
            self.pos[0] = x
        if y!=None:
            self.pos[1] = y

    def __repr__(self):
        return "Animasyon <pos({},{})> <running={}> <index={}>".format(self.pos[0],self.pos[1],self.is_running,int((timer()-self.time)//self.time_interval))

def update():
    """Ana döngüde her defasında bir defa çağırılmalıdır.\npygame.display.update fonksiyonundan önce çağırılması\ntavsiye edilir."""
    time_now = timer()
    liste = animasyonlar[:]
    for a in liste:
        try:
            dis.blit(a.images[int((time_now-a.time)//a.time_interval)],a.pos)
        except IndexError:
            if a.loop:
                a.time = time_now
                dis.blit(a.images[0],a.pos)
            else:
                a.stop()

def from_folder(folder : str):
    """Dosyadaki resimlerden liste oluşturur."""
    dosyalar = listdir(folder)
    images = []
    for i in dosyalar:
        images.append(pygame.image.load(join(folder,i)))
    return images

Örnek bir program:

# örnek
import pygame as pg
import pygame_animation as anim
from threading import Thread

display = pg.display.set_mode((200,200))
anim.init(display)
liste = anim.from_folder("anim")

animasyon = anim.Animation(liste,1.0)
animasyon()
def main():
    while True:
        pg.event.get()

        display.fill((255,255,255))

        anim.update()
        pg.display.update()

Thread(target=main,daemon=True).start()

Örnek programı çalıştırabilmek için dosyalarınız şu şekilde olmalıdır:

örnek.py
pygame_animation.py
anim
 ┣ 1.png
 ┣ 2.png
 ┣ 3.png
 ┗ 4.png

Modülümüz şu şeklide çalışmaktadır:

  • İlk başta pygame_animation.init fonksiyonunu oyun ekranımızı argüman olarak verip çağırıyoruz.
  • pygame_animation.update fonksiyonunu ana döngümüzde her seferinde bir defa çağırıyoruz.
  • Animasyon oluşturmak için pygame_animation.Animation sınıfını kullanıyoruz. Bu sınıfın images parametresi animasyonda kullanılacak resimlerin sırasına göre bulunduğu bir liste.
    time_interval parametresi animasyon sahneleri arasında beklenecek zaman (saniye cinsinden). loop parametresi True ise animasyon tamamlandığında başa sarar, False ise animasyon sonlandığında bitirilir.
  • from_folder fonksiyonu kendisine argüman olarak verilen klasör adresindeki dosyaları sırası ile pygame.Surface sınıfına dönüştürerek Animation sınıfının images parametresi için kullanılabilecek bir liste döndürür. Verilen klasörün içindeki bütün dosyalar birer resim dosyası olmalıdır.
  • Animation.set_pos örnek metodu animasyonlarımızın ekrana çizileceği posizyonu belirlemek için set_pos(x=1,y=1) şeklinde kullanılır.
  • Animation.start örnek metodu animasyonumuzu başlatır.
  • Animation.stop örnek metodu animasyonumuzu durdurur. Tekrar başlatıldığında animasyon en baştan başlayacaktır.
  • Animation.jump örnek metodu animasyonumuzun, kendi resim listesinin argüman olarak verilen index’inden devam etmesini sağlar.
1 Like