Pygame, başlangıç ekranı

Merhabalar basit bir oyun yaptım ve başlangıç ekranı eklemek istiyorum. Aklımdaki fikir şu: starting_screen.py diye bir dosya oluşturup main.py dosyasını import edeceğim. starting_screen’de entere basılınca main.py açılacak. Böyle bir şey mümkün müdür?

veya main.py girişinde starting_screen’i çalıştır başta ardından döngü devam etsin

1 Beğeni

İmport kullandığınızda birden fazla pygame penceresi açamazsınız malesef. İkinci bir pencere açıldığında ilki kapanacaktır. 2 pencereyi aynı anda çalıştırmak için şöyle yapabilirsiniz. run.bat isimli bir dosya oluşturup içeriğini “python main.py” olarak ayarlayabilirsiniz. Sonrasında starting_screen.py içerisinde

import os
os.startfile("run.bat")

yapabilirsiniz.
Şöyle bir örnek paylaşayım, butonlar ekleyebildiğiniz, pygame ile hazırlanmış basit bir arayüz var. Butona tıklandığında main.py’nin çalışması için gerekli kodu ekleyebilirsiniz. Fakat ondan önce Enter tuşuna basınca nasıl yapabileceğinizi kısaca şöyle göstereyim.

    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RETURN:
                # Kodlarınız

Bunu döngünüzün içerisine ekleyebilirsiniz.

Şu kodlar da bahsini ettiğim arayüz.

import pygame
import time
import os

fps = 100
pygame.font.init()


class Screen:
    def __init__(self):
        self.width, self.height = 250, 500
        self.screen = pygame.display.set_mode((self.width, self.height))

    def start(self):
        print(f"Current Screen Resolution is {self.width}*{self.height}")
        pygame.init()

    def update(self):
        pygame.display.update()

    def fill(self, color):
        self.screen.fill(color)

    def change_resolution(self, new_width, new_height):
        self.width, self.height = new_width, new_height
        self.screen = pygame.display.set_mode((self.width, self.height), 0, 32)


Screen = Screen()


class Buttons:
    def __init__(self):
        self.buttons = []

    def add(self, x, y, width, height, color, text, text_color):
        self.buttons.append(Button(x, y, width, height, color, text, text_color))

    def show(self, button_list):
        if button_list == "all":
            for button in self.buttons:
                button.show()
        else:
            for button in button_list:
                try:
                    self.buttons[button].show()
                except IndexError:
                    continue

    def check_for_collision(self, m_x, m_y):
        for button in self.buttons:
            if button.x <= m_x <= button.x + button.width and button.y <= m_y <= button.y + button.height:
                button.collision_with_cursor(mod=True)
            else:
                button.collision_with_cursor(mod=False)

    def check_for_click(self, m_x, m_y):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                for button in self.buttons:
                    if button.x <= m_x <= button.x + button.width and button.y <= m_y <= button.y + button.height:
                        button.clicked()


class Button:
    def __init__(self, x, y, width, height, color, string, text_color):
        self.x, self.y = x, y
        self.width, self.height = width, height
        self.color = color
        self.font = pygame.font.SysFont('Corbel', 35)
        self.text_length = len(string)
        self.string = string
        self.active = False
        self.text_color = text_color
        self.text = self.font.render(self.string, True, self.text_color)
        self.posx = self.x + self.width // 2 - self.text_length * 8.4
        self.posy = self.y + self.height // 2 - 18

    def add_to_buttons(self):
        Buttons.buttons.append(self)

    def show(self):
        pygame.draw.rect(Screen.screen, self.color, [self.x, self.y, self.width, self.height])
        Screen.screen.blit(self.text, (self.posx, self.posy))

    def make_centered(self, reversed=False):
        if not reversed:
            self.x = Screen.width / 2 - self.width / 2
        else:
            self.y = Screen.height / 2 - self.height / 2

        self.posx = self.x + self.width // 2 - self.text_length * 8.4
        self.posy = self.y + self.height // 2 - 18


class StartButton(Button):
    def __init__(self):
        super().__init__(
            x=0,
            y=150,
            width=200,
            height=100,
            color=(255, 0, 0),
            string="Start",
            text_color=(0, 0, 0)
        )

    def clicked(self):
        if self.active:
            self.active = False
        else:
            os.startfile("run.bat")
            self.active = True

    def collision_with_cursor(self, mod=False):
        if not mod:
            self.color = (255, 0, 0)
        else:
            self.color = (140, 0, 0)


class QuitButton(Button):
    def __init__(self):
        super().__init__(
            x=0,
            y=275,
            width=200,
            height=100,
            color=(255, 0, 0),
            string="Quit",
            text_color=(0, 0, 0)
        )

    def clicked(self):
        if self.active:
            self.active = False
        else:
            self.active = True
            quit()

    def collision_with_cursor(self, mod=False):
        if not mod:
            self.color = (255, 0, 0)
        else:
            self.color = (140, 0, 0)


Buttons = Buttons()
StartButton = StartButton()
QuitButton = QuitButton()


def loop():
    Screen.start()

    StartButton.add_to_buttons()
    StartButton.make_centered()
    QuitButton.add_to_buttons()
    QuitButton.make_centered()

    while True:
        Screen.fill((0, 0, 0))
        m_x, m_y = pygame.mouse.get_pos()
        Buttons.show("all")
        Buttons.check_for_collision(m_x, m_y)
        Buttons.check_for_click(m_x, m_y)
        Screen.update()
        time.sleep(1 / fps)


loop()

collision_with_cursor() fonksiyonu, fare imleci butonun üzerine geldiğinde butonun rengini değiştirdiğiniz fonksiyon.
clicked() fonksiyonu butona tıklandığında ne olacağını belirttiğimiz fonksiyon. (Aktif/Deaktif şeklinde çalışmaktadır. Dilerseniz oradaki koşul cümlesini kaldırıp, tıklandığında hep aynı reaksiyonu göstermesini sağlayabilirsiniz.)

make_centered() fonksiyonu ise butonları pencerenin genişliğine göre ortalamaya yarıyor.

Tüm butonları Buttons sınıfına ait self.buttons listesine ekleyerek (Örn: StartButton.add_to_buttons()), gerekli kodları daha az satırda halledebiliyoruz.

Gerisi zaten genel olarak bilinen İngilizce kelimelerden ve sıradanlaşmış pygame kodlarından oluşuyor. Umarım faydası dokunur. İyi çalışmalar.

2 Beğeni

import pygame
import sys

Pygame’i başlat

pygame.init()

Ekran boyutları

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

Renkler

WHITE = (255, 255, 255)
BLACK = (0, 0, 0)

Ekranı oluştur

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption(“Basit Platform Oyunu”)

Saat nesnesi (FPS kontrolü için)

clock = pygame.time.Clock()

Oyuncu sınıfı

class Player(pygame.sprite.Sprite):
def init(self):
super().init()
self.image = pygame.Surface((50, 50))
self.image.fill(WHITE)
self.rect = self.image.get_rect()
self.rect.x = 100
self.rect.y = SCREEN_HEIGHT - self.rect.height - 100
self.change_x = 0
self.change_y = 0
self.jump_speed = -15
self.gravity = 1

def update(self):
    self.calc_grav()

    # Hareketi güncelle
    self.rect.x += self.change_x

    # Engel var mı kontrol et
    platform_hit_list = pygame.sprite.spritecollide(self, platforms, False)
    for platform in platform_hit_list:
        if self.change_x > 0:
            self.rect.right = platform.rect.left
        elif self.change_x < 0:
            self.rect.left = platform.rect.right

    self.rect.y += self.change_y

    # Engel var mı kontrol et
    platform_hit_list = pygame.sprite.spritecollide(self, platforms, False)
    for platform in platform_hit_list:
        if self.change_y > 0:
            self.rect.bottom = platform.rect.top
        elif self.change_y < 0:
            self.rect.top = platform.rect.bottom
        self.change_y = 0

def calc_grav(self):
    if self.change_y == 0:
        self.change_y = 1
    else:
        self.change_y += self.gravity

    if self.rect.y >= SCREEN_HEIGHT - self.rect.height and self.change_y >= 0:
        self.change_y = 0
        self.rect.y = SCREEN_HEIGHT - self.rect.height

def jump(self):
    self.rect.y += 2
    platform_hit_list = pygame.sprite.spritecollide(self, platforms, False)
    self.rect.y -= 2

    if len(platform_hit_list) > 0 or self.rect.bottom >= SCREEN_HEIGHT:
        self.change_y = self.jump_speed

def go_left(self):
    self.change_x = -6

def go_right(self):
    self.change_x = 6

def stop(self):
    self.change_x = 0

Platform sınıfı

class Platform(pygame.sprite.Sprite):
def init(self, width, height, x, y):
super().init()
self.image = pygame.Surface((width, height))
self.image.fill(WHITE)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y

Sprite grupları

all_sprites = pygame.sprite.Group()
platforms = pygame.sprite.Group()

Oyuncu nesnesini oluştur

player = Player()
all_sprites.add(player)

Platformları oluştur

platform = Platform(200, 20, 200, 400)
all_sprites.add(platform)
platforms.add(platform)

platform = Platform(200, 20, 500, 300)
all_sprites.add(platform)
platforms.add(platform)

Ana döngü

running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player.go_left()
if event.key == pygame.K_RIGHT:
player.go_right()
if event.key == pygame.K_SPACE:
player.jump()
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT and player.change_x < 0:
player.stop()
if event.key == pygame.K_RIGHT and player.change_x > 0:
player.stop()

# Tüm sprite'ları güncelle
all_sprites.update()

# Ekranı beyaza boyama
screen.fill(BLACK)

# Tüm sprite'ları çiz
all_sprites.draw(screen)

# Ekranı güncelle
pygame.display.flip()

# FPS kontrolü
clock.tick(60)

pygame.quit()
sys.exit()