Çoktandır blogla ilgilenmiyordum. Dün akşam tasarımı baştan aşağı değiştirdikten sonra tekrar yazma isteği uyandı. Ne yazabilirim diye düşünürken, yarım kalan projeler içindeki RPG oyununu buldum. Hem Türkçe kaynak olur hem de projeyi tamamlarım diyerekten bu yazı dizisini başlatmaya karar verdim.

PyGame ile 2D RPG Oyunu Yapalım (1. Bölüm)
Bendeki projenin son hali şuanda böyle.

Haritadaki bozuklukların sebebi spritesheet'i internetten bulmak yerine elle çizmeyi tercih etmem. Her kareyi (tile) ihtiyaç oldukça çiziyordum. Neyse...

Proje Yapısı

Önce oyun projesini oluşturup gerekli klasörleri, modülleri vs. oluşturalım.

Proje Dizini
├── core
│   ├── characters
│   │   ├── __init__.py
│   │   └── player.py
│   │
│   ├── managers
│   │   ├── __init__.py
│   │   ├── resourcemanager.py
│   │   └── tilemanager.py
│   │
│   ├── maps
│   │   ├── __init__.py
│   │   └── island.py
│   │
│   ├── mobs
│   │   └── __init__.py
│   │
│   ├── tiles
│   │   └── __init__.py
│   │
│   └── __init__.py
│
├── data
│   ├── maps
│   ├── sprites
│   └── tiles
│
└── main.py

Oyun modülleri core klasöründe, resim, map ya da xml gibi kaynak dosyaları da data klasöründe duracak.

Klasörlerin içindeki __init__.py dosyaları, klasörleri python paketi olarak görmesini sağlamak için. Çalıştığımız dosyaya from characters.player import Player gibi import etmemize yarayacak.

Oyun Modülü ve Yaşam Döngüsü

Oyunun ana modülü main.py olacak. PyGame benim sistemde kurulu olduğu için virtualenv kullanma gereği duymadım eğer isterseniz şuraya bakabilirsiniz.

Şimdi main.py içine gelip aşağıdaki gibi ya da buna benzer bir sınıf oluşturun.

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

import pygame


class Game:
    def __init__(self, display, flags, depth):
        pygame.init()
        pygame.display.set_caption("2D RPG")
        self.screen = pygame.display.set_mode(display, flags, depth)
        self.running = True

    clock = pygame.time.Clock()
    fps = 30

    __pressed = {}

    def start(self):
        self.load()
        self.loop()

    def load(self):
        pass

    def loop(self):
        while self.running:
            self.events()
            self.update()
            self.render()
            self.clock.tick(self.fps)

    def update(self):
        pass

    def render(self):
        self.screen.fill((255, 255, 255))

        # render işleri

        pygame.display.update()

    def events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
                pygame.quit()
            elif event.type == pygame.KEYDOWN or event.type == pygame.KEYUP:
                self.__pressed[str(event.key)] = event.type == pygame.KEYDOWN

if __name__ == "__main__":
    game = Game((800, 600), 0, 32)
    game.start()

Game sınıfı içinde önce __init__ fonksiyonunda PyGame'i hazırlayıp, pencere başlığını belirleyip, çalışma alanını (self.screen) belirledik. Pencere değişkenleri sınıfın oluşturulması esnasında parametre olarak geliyor.

Sınıf içindeki clock oyun zamanını, fps bir saniyede oynatılacak görüntü sayısını, __pressed o an basılı olan klavye tuşlarını tutacak.

Oyun döngesi loop fonksiyonu içinde. Sırasıyla events ile oyun olaylarını (tıklama, tuşa basma vs.) kontrol edecek, update ile -oyuncu, düşman gibi- oyun objelerinin özelliklerini belirleyecek, render ile ekrana basılması gereken resimleri çizecek ve son olarak clock.tick ile oyun saatini ilerletecek.

Events fonksiyonunda o anda oyun içinde gerçekleşen olaylar (pygame.event.get) içinden işimize yarayan eventleri aldık. Oyun kapatıldığında oyun yaşam döngüsünü kontrol eden running değişkeni False oldu. Eğer klavyeden bir tuşa basılmış (Key Down) ya da tuştan el çekilmişse (Key Up) __pressed içindeki tuş değeri True ya da False oldu.

Son olarak oyun sınıfının -gerekli parametreleri vererek- bir örneğini oluşturup start fonksiyonu ile başlattık. Hiç bir sorun yoksa python main.py yaptığınızda karşınıza siyah bir ekran gelecektir.

Sonraki bölüm: Oyuncu Hareketi ve Animasyon