• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Czy taka struktura programu w SFML ma prawo bytu?

0 głosów
93 wizyt
pytanie zadane 9 lipca 2018 w C i C++ przez Jakub 0 Stary wyjadacz (12,500 p.)
zamknięte 10 lipca 2018 przez Jakub 0

Witam, tworzę gierkę w SFML. Może powiem trochę jak wygląda u mnie wzorzec programu. Mam klasę o nazwie Program. Tam jest składowa typu sf::RenderWindow (okno) oraz najbardziej zewnętrzna pętla całego programu zawarta w publicznej metodzie o nazwie run() wywoływana bezpośrednio przez main(). Powiedziałem pętla programu a nie gry bo będzie też menu główne. Wobec tego mamy dwie dodatkowe klasy: GameProcess i MenuProcess, zawierają one odpowiednie składowe w sekcji prywatnej oraz metody loop(), metody te zawierają odpowiednio pętlę gry dla programu i samej gry, metoda loop() zwraca odpowiednie komunikaty dla głównej pętli gry we wspomnianej metodzie run() w klasie Program. Dzięki temu możemy te komunikaty odpowiednio obsługiwać i tym samym zmieniać wskaźnik na inne instancje programu ( bo właśnie, chyba zrobię to tak klasy GameProcess i MenuProcess będą dziedziczyć z jednej abstrakcyjnej klasy bazowej o nazwie Process ):

Jest jednak pewna kwestia, metody wszystkich klas dziedziczących z Process będą potrzebowały używać okna gry stworzonego w konstruktorze klasy Program. Początkowo miałem dostarczać referencje na okno gry każdej  funkcji z osobna która go potrzebuje. Zrobiłem jednak tak że w klasie ( na razie GameProcess ) mamy prywatną składową będącą referencją na okno gry ( inicjalizowaną w konstruktorze tej klasy za pomocą listy inicjalizacyjnej ):

//(przypominam że jeszcze nie zrobiłem głównej klasy Abstrakcyjnej, więc na razie pokazana klasa jeszcze z niej nie dziedziczy )

class GameProcess {
public:
	GameProcess(sf::RenderWindow& win, Player pl);
	signals loop();
private:
	Player player; 
	sf::RenderWindow& r_window; //referencja
};

Każda metoda klasy GameProcessing ma do okna dostęp. Czy jednak jest to dobry i bezpieczny pomysł czy "może się na mnie zemścić" w przyszłości ?

Wolę się upewnić co o tym sądzicie już teraz by potem nie mieć problemów. Z góry dziękuje za rady wink

komentarz zamknięcia: temat wyczerpany

2 odpowiedzi

+1 głos
odpowiedź 9 lipca 2018 przez Criss Mędrzec (169,580 p.)
wybrane 10 lipca 2018 przez Jakub 0
 
Najlepsza
Generalnie IMHO jest ok, ale przekazywanie obiektu okna każdej metodzie która go potrzebuje było wg mnie lepszym pomysłem. Dzięki temu możesz z poziomu klasy Program podawać dowolny RenderTarget (tekstura, inne okno?) na który GameProcess lub MenuProcess ma narysować. Teraz może ci się to wydawać niepotrzebne, bo nie widzisz na razie potrzeby rysowania do czegokolwiek innego niż główne okno. Ale w trakcie rozbudowy projektu jeśli podejmiesz decyzje o istnieniu wielu render targetów, zaoszczędzi ci to przebudowy projektu. To jedyne do czego bym się przczepił z kwestii designerskich.

To oczywiście twoja sprawa, ale nazwy GameProcess i MenuProcess sugerują osobny proces (w sensie punktu widzenia systemu operacyjnego). Przynajmniej ja tak to widzę... Być może warto rozważyć zmianę nazwy?

Zainteresuj się wzorcem projektowym "state", bo to co teraz tworzysz aż prosi się o jego wykorzystanie i wyraźnie idzie w tą stronę. Klasy GameProcess i MenuProcess mogłyby być klasami obsługującymi stany klasy Program i dziedziczyć z jakiejś abstrakcyjnej klasy Program::State.
edit odnośnie Program::State - chyba masz już taką klasę (Process) :P
komentarz 10 lipca 2018 przez Jakub 0 Stary wyjadacz (12,500 p.)

Jak tak patrzę to praktycznie już nieświadomie zastosowałem idee tego wzorca ( tyle że u mnie jak na razie zmienia się tylko stan metody run() klasy Program ( lokalny wskaźnik - bo już zrobiłem ten polimorfizm ) a nie stan całej klasy. To oczywiście mogę łatwo przebudować.

przekazywanie obiektu okna każdej metodzie która go potrzebuje było wg mnie lepszym pomysłem.

Swoją drogą racja, metoda loop() w klasach dziedziczących z Process jest jedyną składową publiczną. Wobec tego jej można dać referencje na okno a ona wywołuje w pętli pozostałe metody i ewentualnie przekazuje im okno. Tyle że wcześniej chciałem iść trochę na łatwizne.

To oczywiście twoja sprawa, ale nazwy GameProcess i MenuProcess sugerują osobny proces (w sensie punktu widzenia systemu operacyjnego). Przynajmniej ja tak to widzę... Być może warto rozważyć zmianę nazwy?

Cóż, te klasy symbolizują pewnego rodzaju "proces" tyle że na wyższym ( w mojej grze ) poziomie abstrakcji ;) Czyli wskaźnik w klasie Program wskazuje na wykonywany proces. ( Wcześniej zamiast proces było Processing czyli przetwarzanie, przetwarzanie danych gry lub danych menu zależnie od wartości wskaźnika ).  Ale fakt że może być to mylące z procesem w systemie. Przy zmianie nazw trochę się narobię bo w wielu miejscach ich używam...

komentarz 10 lipca 2018 przez Jakub 0 Stary wyjadacz (12,500 p.)

@Criss

Przepraszam że tak bardzo rozciągam temat ale mam jeszcze jedno nurtujące mnie pytanie, mam w jednym pliku zbiór klas dziedziczących z jednej abstrakcyjnej opisujące dany stan programu. Mam też oczywiście klasę Program z główną pętlą. I Plik z klasą Program i ten z klasami ze stanami programu potrzebują mieć dostęp do pewnego typu wyliczeniowego ( z nazwami odpowiednich komunikatów które zwracają metody loop() z klas stanów  które odbiera metoda run() klasy Program. Gdzie te wyliczenia/stałe najlepiej powinny się znajdować?

W osobnym pliku nagłówkowym który dołączmy do obu plików:

Czy może w pliku z klasami stanu gry, wtedy z tych stałych będzie mogła też korzystać klasa Program kiedy do jej pliku dodamy plik ze wspomnianymi klasami:

Mam na dzieje że chociaż po rysunkach wiadomo o co mi znowu chodzi ;)

 

komentarz 10 lipca 2018 przez Criss Mędrzec (169,580 p.)

Najwygodniej w osobnym pliku wg mnie, więc może tak?

Przy zmianie nazw trochę się narobię bo w wielu miejscach ich używam...

Jeśli tobie to odpowiada, to zostaw. Nic na siłę :P Btw. jeśli korzystasz z VS, to masz tam taki fajny skrót klawiszowy ctrl+R, ctrl+R (trzymasz ctrl i dwa razy naciskasz R) i pojawia ci się okienko do zmiany nazwy zmiennej/klasy/funkcji a VS odwala robote. https://msdn.microsoft.com/en-us/library/da5kh0wa.aspx#bkmk_refactor 

komentarz 10 lipca 2018 przez Jakub 0 Stary wyjadacz (12,500 p.)
Dzięki wielkie za ten skrót klawiszowy ;)

* oraz link do innych ( nie miałem o nich pojęcia )
0 głosów
odpowiedź 9 lipca 2018 przez Munvik Dyskutant (8,270 p.)

Najlepiej to przekaż wskaźnik na sf::RenderWindow obu klasom (GameProcess i MenuProcess).

Zrób jeszcze 1 klasę taką jeszcze najbardziej zewnetrzna czyli Game. Niech ona będzie singletonem.

Niech ona trzyma takie coś jak sf::RenderWindow i wskaźnik na Process (Process * controler). 

Jeżeli chcesz wyjść z menu to odwołaj się do tego obiektu. Jak to zrobić ? No to jest singleton czyli posiada statyczny wskaznik na siebie. Cos takiego

Game::getController()->setController(Process *GameProcess)

Takim czyms zmienisz stan gry na grę. Pytaj jak czegos nie wiesz.

Podobne pytania

+3 głosów
2 odpowiedzi 201 wizyt
pytanie zadane 18 czerwca 2018 w Nasze projekty przez Michał Gibas Pasjonat (15,390 p.)
+3 głosów
1 odpowiedź 205 wizyt
0 głosów
0 odpowiedzi 84 wizyt
pytanie zadane 14 marca 2018 w C i C++ przez zpawlo00 Początkujący (310 p.)
Porady nie od parady
Zadając pytanie postaraj się o odpowiedni tytuł, kategorię oraz tagi.Tagi

63,338 zapytań

109,598 odpowiedzi

228,958 komentarzy

44,170 pasjonatów

Przeglądających: 203
Pasjonatów: 7 Gości: 196

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...