Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SFML] TWORZENIE GRY: pętle, szlielet , rozdzielczość itd.

Ostatnio zmodyfikowano 2017-01-14 16:21
Autor Wiadomość
zqick
Temat założony przez niniejszego użytkownika
[SFML] TWORZENIE GRY: pętle, szlielet , rozdzielczość itd.
» 2017-01-12 16:15:35
Witam ostatnio pisze małą gierkę platformową w SFML , i mam kilka pytań:
 1. Rozdzielczość Okna , jaka ? na razie mam tylko 3 pomysły:
  - stała np 1280x720 (komuś może się nie zmieścić , a u kogo innego być w malutkim okienku)
  - po prostu skalowanie :P (utrata jakość)
  -wszystko rysować w taki sposób żeby się zmieściło w 1024x768 , a dalej tylko nic nieznacząca grafika żeby nie było czarne , np do 1920x1080. 
   i środkować widok. ( dziwnie będzie to wyglądać na dużych monitorach)
  -wszystkie współrzędne i rozmiary zapisywać za pomocą ułamka: 1.5 , 0.25 , 0.005 ... . i mnożyć razy wysokość okna. ( nwm. jak będzie z jakością
    i czy nie potrzebnie będzie obciążać procesor)
  - coś innego :P
 2. Szkielet Gry:
  - Enum i pętla główna w której jest switch sprawdzający aktualny status gry.
  - W pętli głównej wskaźnik na abstrakcyjną klasę Scenę , która ma funkcje: update(), draw() ... (jeśli ta metoda będzie dobra to jeszcze
   jedno pytanie czy zmieniać scenę , po przez jakiś Manager , czy po prostu update zwraca *Scene , i jeśli jest różne od nullptr , to podmienia)
  - coś innego :P
 3. Podstawowe dane typu ( sf::renderWindow , sf::Event) trzymać:
  - Przekazywać w argumentach ( najlepsza opcja , tylko wchodzi w zależność cykliczną z *Scene )
  - po prostu jako zmienne globalne :(
  - jakiś Singleton
  - coś innego
 4. Pętla gry rzeczywista czy Stało krokowa ?   
 5. Kolizja PixelPerfect czy SAT (lub jakieś inne matematyczne , tylko nie bounding box , bo zależy mi na dokładność) , chodzi mi tylko oto żeby
    nie "zabić" maszyny , oczywiste że PixelPerfect jest dużo bardziej wymagający. Ale czy przy dużej liczbie obiektów , nie będzie szybszy niż SAT 
    (najpierw sprawdzam kolizje na Bouding Box'ach , a jak zajdzie dopiero SAT ) Pytam się dlatego że nigdy nie stosowałem PixelPerfect ,tylko
    zawsze matematyczne , i nie mam porównania :P
 6. Czy to obliczeń i fizyki (pisze sam) stosować współrzędne np. z sprite ,w sensie "sprite.getPosition().x" czy mieć swoje odpowiedniki w klasie?
 7. Opakować Klasy SFML w własne (trochę zabawy jest , ale daje dużo większe możliwość poratowania) ?
 8. Rozdzielić Logikę i Widok Obiektu na dwie klasy , czy wystarczy jedna ?
 9. Czy da się jakoś wczytać grafikę, muzykę .. bez zacinania okienka , i bez wielowątkowości ?

i jeśli ktoś by mógł napisać jakieś sprawdzone sposoby organizowania kodu , lub jakąś książkę , kurs (mam "czysty kod") , byłbym wdzięczny :D
Dziękuje , że wytrwałeś aż dotąd, i jeśli możesz prosiłbym o szybką odpowiedz , nawet choćby tylko na jedno z moich pytań :P
 



P-156361
Gibas11
» 2017-01-12 21:54:48
1. Częściowo skaluj (zapewnij grafiki pozwalające na prawdidłowe wyświetlanie do np. 5K) i częściowo powiększaj pole widzenia.
2. No ja bym zrobił jakąś maszynę stanów, poszukaj w internecie (jest tego pełno) i wybierz jaka konstrukcja najbardziej ci pasuje.
3. W argumentach, dobrze zorganizujesz kod i ew. użyjesz predeklaracji to wszystko zadziała.
4. Obojętne (najlepiej zostaw to do wyboru użytkownikowi, sztuczny limit klatek / v-sync / brak limitu) i mierz w pętli czas co iterację a na nim opieraj całą logikę.
5. Zależy od tego jakiej oczekujesz wydajności / dokładności, ale z reguły PixelPerfect zawsze działa dobrze i prawie na pewno nie masz się tym co przejmować.
6. Mogą być te z sf::Sprite, ale pamiętaj uwzględnić gdzie jest środek sprite.
7. Co? W większości wypadków nie widzę zastosowań, generalnie praktycznie nigdzie.
8. Z reguły jedna jest ok.
9. Opcje są dwie:
    - masz dostępny dysk na tyle szybki, żeby okienko się nie zacięło.
    - Nie.
Akurat przypadkiem ostatnio napisałem bibliotekę ładującą w osobnym wątku zasoby (właściwie robi dużo więcej, ale to ci się może przydać), możesz ją obczaić, nie chciało mi się tego jeszcze udokumentować, ale tu masz przykład wykorzystania tej części.
P-156374
mokrowski
» 2017-01-12 22:08:26
Tu masz repozytorium do bardzo dobrej książki o organizacji kodu, budowania pętli gry, maszyny stanu https://github.com/Krozark​/SFML-book Są tam odnośniki do samej książki.
P-156376
zqick
Temat założony przez niniejszego użytkownika
» 2017-01-13 00:16:02
Dzięki :D
P-156379
RazzorFlame
» 2017-01-13 19:55:02
5. Zależy od tego jakiej oczekujesz wydajności / dokładności, ale z reguły PixelPerfect zawsze działa dobrze i prawie na pewno nie masz się tym co przejmować.
6. Mogą być te z sf::Sprite, ale pamiętaj uwzględnić gdzie jest środek sprite.
7. Co? W większości wypadków nie widzę zastosowań, generalnie praktycznie nigdzie.

5. Zwykle kolizje nie opierają się w ogóle na tym co jest wyświetlane. W grach 3D generuje się tzw. convex shapy do kolizji, które są uproszczeniem modelu. Kolizja PixelPerfect jest bezsensowna dla platformówek (dopóki nie robi się czegoś w stylu worms, chociaż to też można by było fajniej zoptymalizować) i dużo lepiej jest całkowicie odciąć kolizje od sprajta na rzecz zestawu połączonych prymitywów. Dlatego autorze, tak jak napisałem na grupie na FB - skorzystaj z Box2D i oprzyj kolizje na prostych figurach geometrycznych.
6. To samo co u góry. To jest zastosowanie dla bardzo małych projekcików i bardzo ogranicza późniejsze rozbudowywanie.
7. Przykro mi ale jesteś w błędzie. Co jeśli jakikolwiek obiekt będzie się składał z grupy różnych komponentów? Wtedy albo musisz opakować sobie to w własną klasę (lepsze rozwiązanie) albo stworzyć klasę pochodną od np. sf::Drawable (gorsze rozwiązanie) a to wszystko sprowadza się tak naprawdę do tego samego.
Opakowywanie domyślnych bibliotekowych klas jest praktycznie wszędzie pożądane chyba, że robisz naprawdę malutki projekt.
P-156387
Gibas11
» 2017-01-13 23:53:56
5. Zwykle kolizje nie opierają się w ogóle na tym co jest wyświetlane. W grach 3D generuje się tzw. convex shapy do kolizji, które są uproszczeniem modelu. Kolizja PixelPerfect jest bezsensowna dla platformówek (dopóki nie robi się czegoś w stylu worms, chociaż to też można by było fajniej zoptymalizować) i dużo lepiej jest całkowicie odciąć kolizje od sprajta na rzecz zestawu połączonych prymitywów. Dlatego autorze, tak jak napisałem na grupie na FB - skorzystaj z Box2D i oprzyj kolizje na prostych figurach geometrycznych.
6. To samo co u góry. To jest zastosowanie dla bardzo małych projekcików i bardzo ogranicza późniejsze rozbudowywanie.
7. Przykro mi ale jesteś w błędzie. Co jeśli jakikolwiek obiekt będzie się składał z grupy różnych komponentów? Wtedy albo musisz opakować sobie to w własną klasę (lepsze rozwiązanie) albo stworzyć klasę pochodną od np. sf::Drawable (gorsze rozwiązanie) a to wszystko sprowadza się tak naprawdę do tego samego.
Opakowywanie domyślnych bibliotekowych klas jest praktycznie wszędzie pożądane chyba, że robisz naprawdę malutki projekt.
5. Nie tylko, w strzelankach też z reguły warto użyć perfekcyjnych pikselowych kolizji, zależy co dokładnie będzie się działo w tej platformówce.
6. Nie bardzo, dobrze dziedzicząc po klasach SFML i organizując projekt da się tego spokojnie tak używać nawet w średnich tworach a OP w końcu pisze „małą” platformówkę, nie?
7. Co jest złego w dziedziczeniu po sf::Drawable i wyświetleniu stamtąd wszystkich komponentów? Zwłaszcza, że ułatwia to potem przekazywanie tego obiektu gdziekolwiek gdzie oczekiwana jest instancja sf::Drawable. Oczywiście pisząc coś serio dużego może rzeczywiście pojawiłaby się potrzeba zrobienia czegoś takiego, ale w dobrze zorganizowanym kodzie ogromne klasy powinny być spotykane równie rzadko co goto. ;)
P-156398
RazzorFlame
» 2017-01-14 00:39:06
5. Nie tylko, w strzelankach też z reguły warto użyć perfekcyjnych pikselowych kolizji, zależy co dokładnie będzie się działo w tej platformówce.
6. Nie bardzo, dobrze dziedzicząc po klasach SFML i organizując projekt da się tego spokojnie tak używać nawet w średnich tworach a OP w końcu pisze „małą” platformówkę, nie?
7. Co jest złego w dziedziczeniu po sf::Drawable i wyświetleniu stamtąd wszystkich komponentów? Zwłaszcza, że ułatwia to potem przekazywanie tego obiektu gdziekolwiek gdzie oczekiwana jest instancja sf::Drawable. Oczywiście pisząc coś serio dużego może rzeczywiście pojawiłaby się potrzeba zrobienia czegoś takiego, ale w dobrze zorganizowanym kodzie ogromne klasy powinny być spotykane równie rzadko co goto. ;)
5. Kolizja pixel-perfect mógłbym powiedzieć śmiało jest w takim przypadku amatorska. W strzelankach 2D nie ma najmniejszej potrzeby, żeby używać kolizji pixel perfect jeśli użyjesz figur geometrycznych i przy tym wiesz co robisz.
6. Nie wątpię, że się da. Pytanie tylko jak głupim jest uzależnianie od jednego wyświetlanego obiektu całej grupy wchodzącej w skład np. naszej postaci.
7. Nie napisałem, że to rozwiązanie jest złe tylko, że jest gorsze od napisania własnej klasy.
Rozważ taki przypadek. Piszesz sobie klasę uzależnioną od sf::Drawable. Po jakimś czasie twórca SFML postanawia, że przydałoby się trochę zmodernizować kod i zmienia klasę sf::Drawable w jakimś większym stopniu. Co wtedy? Musisz dostosować swoją klasę, wykonać więcej roboty niż gdybyś elementy SFML miał jako tylko część swojej klasy. Mając napisaną własną hierarchie klas, niezależną od żadnej biblioteki jedyne co musisz zmieniać jest kod źródłowy swojej klasy, sam wzorzec jest praktycznie taki sam.
To samo stało się gdy Laurent (twórca SFML) wprowadził SFML 2.0 i zmienił konwencję nazywania metod i kilka innych rzeczy. Dajmy na to masz taki kod:
C/C++
// Kod dla SFML 1.6
class CPlayer
    : public sf::Drawable
{
public:
    CPlayer() { }
   
    virtual void Draw( sf::RenderTarget & target, sf::RenderStates states )
    {
        target.Draw( m_sprite, states );
    }
protected:
    sf::Sprite m_sprite;
};
Kod jest pisany z palca ale dobrze oddaje to o co mi chodzi. Teraz pomyśl - masz narzuconą konwencję nazewnictwa przez autora SFML, musisz się dostosować np. do tego, że metody zaczynały się wtedy z wielkiej litery. I tak sobie piszesz kod, piszesz piszesz. Masz powiedzmy... 10000 linijek kodu. Średni projekt gry ale jesteś z siebie dumny bo wszystko działa itp. W takim projekcie powiedzmy masz 300 wywołań funkcji Draw z klasy CPlayer. Nagle Laurent wypuszcza SFML 2.0 - o niebo lepszą wersję niż Ty masz aktualnie. Musisz ją mieć. Ściągasz, instalujesz, dostosowujesz projekt, kompilujesz - i co? Masz zonka bo masz kilkaset błędów przez jedną funkcję. Pomyśl sobie, gdybyś dodatkowo dziedziczył po sf::Transformable? Tam to dopiero byś dostał błędów. A jedyne co musiałbyś zrobić opakowując to we własną klasę to zmianić w kodzie klasy kilka linijek - nie musisz wtedy nawet zmieniać swojej konwencji nazywania.
Dlatego właśnie opakowywanie jest lepsze niż dziedziczenie - ale tak jak pisałem - w malutkich projektach to nie jest aż tak ważne.

I nie rób kolizji pixel perfect dopóki naprawdę nie ma innego wyjścia.

// Edit:
Z tymi 300 wywołaniami funkcji Draw to przesadziłem ale jeśli funkcji będzie więcej to z łatwością nazbiera się tyle wywołań.
P-156399
Saran
» 2017-01-14 01:02:58
@up wydaje mi się, że każde IDE ma opcję wyszukiwania fraz i zamieniania je na inne frazy, co do tego Draw ;)
P-156401
« 1 » 2 3 4
  Strona 1 z 4 Następna strona