2012-06-19 11 views
6

Tworzę małą grę i chcę zrobić kolejne okno oddzielnie od mojego głównego.Wiele wyświetlaczy w Pygame

Mam główną grę w głównym oknie i chcę otworzyć nowe okno i zrobić małą animację, gdy użytkownik coś robi.

W poniższym przykładowym kodzie poniżej, gdy użytkownik naciśnie "a", chcę, aby otworzył nowe okno i tam się rozmył.

Tu skonfigurować dwa okna: (wiem to robi praca, to, o co pytam, jak to zrobić)

SCREEN_X = 400 
SCREEN_Y = 400 
BSCREEN_X = 240 
BSCREEN_Y = 160 

BATTLE_SCENE = pygame.display.set_mode((BSCREEN_X, BSCREEN_Y)) 
SCREEN = pygame.display.set_mode((SCREEN_X, SCREEN_Y)) 

a następnie program:

def run_ani(): 
    #Do animation, blitting to BATTLE_SCENE 
    return 

def main_game(): 
    ending=False 
    while ending==False: 
     clock.tick(30) 
     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: ending=True 
      if event.type == KEYDOWN: # key down or up? 
       if event.key == K_ESCAPE: 
        ending=True # Time to leave 
        print("Stopped Early by user") 
       elif event.key == K_a: 
        run_ani() 
     #Normal screen motion, blitting to SCREEN 
     if ending: pygame.quit() 
    return 

tej pory to, co robi, rysuje główny ekran, a kiedy A jest wciśnięty, przestaje rysować animacje głównego ekranu, ale nadal rysuje pozostałe animacje na głównym ekranie i rysuje w lewym górnym rogu.

Jestem pewien, że robi to, bo jestem ustawienie BATTLE_SCENE być mniejszy niż na głównym ekranie, a więc gdy blittingiem do BATTLE_SCENE to Blits do obszaru utworzonego (240x160) w górnym rogu ekranu głównego.

Jednak chcę, aby BATTLE_SCENE było oddzielnym oknem, więc gdy naciśnie "a", wyskoczy, zrobi to, zamknie lub przynajmniej przejdzie za główny ekran.

Jak to zrobić? Czy to możliwe?

+0

Nie powinieneś tego robić mimo to. –

+0

Czy to oznacza, że ​​powinienem to zrobić? nieco więcej wyjaśnień byłoby miło :) – hammythepig

+0

Utwórz obszar w istniejącym oknie animacji. –

Odpowiedz

8

Czy naprawdę potrzebujesz wielu okien? Mam na myśli, czy naprawdę ich potrzebujesz?

Jeśli tak, to powinieneś użyć zamiast tego pyglet/cocos2d.

Aby mieć wiele okien w pygame, potrzebujesz wielu procesów (po jednym dla każdego okna). Chociaż jest to wykonalne, nie jest warte swojej siły. Będziesz potrzebował IPC do wymiany danych między oknami, a Twój kod stanie się podatny na błędy i brzydki.

Idź z pyglet, gdy potrzebujesz więcej niż jednego okna.

Lepszym rozwiązaniem jest prawdopodobnie podzielenie Twojej gry na sceny. Twórz wiele scen tak, aby każdy reprezentował jeden etap gry, coś w stylu MenuScene, MainScene, BattleScene, GameOverScene, OptionScene itp.

Następnie pozwól każdej z tych scen obsługiwać wejście/rysunek tej części gry.

  • MenuScene obsługuje rysunek i wejście itp z gry w menu
  • MainScene obsługuje rysowanie i wejście itp gry bieżącą
  • BattleScene uchwyty ciągnącego oraz wejścia itd cokolwiek robisz w run_ani

W pętli głównej wystarczy przekazać kontrolę nad bieżącą sceną, stosując metody: draw(), handle_event() i update().

Niektóre przykładowy kod, aby dostać się pomysł:

scenes = {'Main': MainScene(), 
      'Battle': BattleScene()} #etc 

scene = scenes['Main'] 

class MainScene(): 
    ... 
    def handle_event(self, event): 
    if event.type == KEYUP: 
     if event.key == K_a: 
     scene = scenes['Battle'] 
    ... 

class BattleScene(): 
    ... 
    def draw(self): 
    # draw your animation 

    def update(self): 
    # if animation is over: 
    scene = scenes['Main'] 

... 

def main_game(): 
    ending=False 
    While Not ending: 
     clock.tick(30) 
     for event in pygame.event.get(): 
     scene.handle_event(event) 
     scene.update() 
     scene.draw() 

Jest to prosty sposób na czysto oddzielić logikę gry i umożliwiają przełączanie kontekstowe.

+0

Och, widzę, użyj niektórych klas. Nigdy nie lubiłem lekcji, bo wyglądały na zagmatwane, ale rozumiem, co tam napisałeś. Myślę, że jeszcze zajrzę do klas i nauczę się więcej rzeczy. Na razie biorę ci odpowiedź, to wydaje się być prostym i skutecznym sposobem robienia tego, co chcę, wielkie dzięki! :) – hammythepig

+0

to mądry pomysł, dzielenie się wiedzą o takich rzeczach. Lubię uczyć się wszystkich tych rzeczy, ich ciekawych i zabawnych w tym samym czasie. – hammythepig

1

====================================== Edit ======= ==================================

Właściwie to nie będzie działać. Wyraźnie pygame obsługuje tylko jeden ekran wyświetlacza, a po zainicjowaniu innego zamyka pierwszy. Zostaniesz z dwiema odmianami, które w rzeczywistości są tą samą powierzchnią. Zamiast tego możesz zwiększyć rozmiar okna i odtworzyć scenę bitewną z boku, aby to zrobić, możesz ponownie wywołać funkcję pygame.display.set_mode() z różnymi wartościami. Zmienna, która odnosi się do ekranu wyświetlacza, będzie nadal użyteczna, ponieważ zmieni odniesienie do nowego. Po zakończeniu sceny możesz zmniejszyć okno w ten sam sposób.

============================================== ====================================

Co się dzieje, jest po prostu uruchomić pętlę, a każda iteracja to renderowanie i wyświetlanie nowej ramki. Po wywołaniu funkcji w pętli, nie kontynuuje ona działania, dopóki nie zostanie uruchomiona funkcja.

Jednym ze sposobów rozwiązania tego problen jest po prostu zachować wywołanie funkcji, która aktualizuje scenę bitwy w pętli głównej. Innym sposobem jest użycie wątków. Wątkowanie polega na uruchamianiu wielu skryptów ("wątków") w tym samym czasie.

Na szczęście, python już zaimplementował to dla nas za pomocą modułu wątków. Jest za dużo czasu na wyjaśnienie modułu tutaj, ale można się go nauczyć here. Może to być trochę skomplikowane, jeśli wcześniej nie używasz wątków, ale po pewnym czasie będzie łatwiej. A jeśli chcesz dowiedzieć się więcej o wątkach, możesz przejść na here.

specificly tutaj, można mieć dwa wątki, jeden dla każdej pętli/okna, i uruchomić je w tym samym czasie.

Mam nadzieję, że ci pomogłem!

Powiązane problemy