Podam przykład: jakieś 2 miechy temu chciałem napisać grę rpg, kafelkowa, 2d. Porzuciłem projekt po kilkunastu dniach
Rozumiem po kilku miesiącach, ale po kilkunastu dniach? Wytrwałość jest konieczna, jak chce się coś osiągnąć.
Załóżmy, że chce otworzyć ekwipunek. W tym momencie nie powinienem się ruszać. Trzeba więc dodać zmienną bool isEqOpen
Teraz trzeba wrócić do miejsca w kodzie odpowiadającego za poruszanie się i wprowadzić warunek:
if(isEqOpen == false)
postac.ruch
Tutaj może być problem. Z tego co napisałeś wnioskuję, że traktujesz grę jako monolit z logiką umieszczoną po całej grze, gdzie dodanie jednej rzeczy (ekwipunek) wymaga ruszania kodu w iluś miejscach i ciągłego sprawdzania konkretnych warunków.
A można inaczej. Zamiast sprawdzać konkretny warunek "czy jest otwarty ekwipunek" w konkretnej funkcji "ruszania", można iść trochę wyżej w abstrakcji i dodać coś takiego jak "pauza" i sprawdzać warunek pauzy:
if(isPause == false)
w ten sposób jak dodasz inny powód, dla którego postać miałaby się nie ruszać, nie musiałbyś dodawać nowego warunku i sprawdzać isInMainMenu
tylko ustawiałbyś pauzę i miałbyś spokój.
Być może więc podchodzisz ze złego poziomu abstrakcji, szukasz rozwiązania pojedynczych problemów, zamiast myśleć całościowo i wybiegać w przód o parę kroków.
Po prostu pisze powiedzmy funkcje odpowiedzialną za chodzenie. Po kilku godzinach okazuje się, że moja funkcja jakoś koliduje z inną / trzeba to zrobić inaczej i DUPA
hasła do wygooglowania: decoupling, Single Responsibility Principle, separation of concerns :)
np. czemu w ogóle funkcja odpowiedzialna za chodzenie ma sprawdzać ekwipunek (albo czemu ma sprawdzać warunek pauzy)?
To tak jakby bohaterowie filmu sprawdzali, czy masz wciśnięty przycisk pauzy w odtwarzaczu.
Takie rzeczy lepiej sprawdzać na wyższym poziomie kontroli, np. w głównej pętli gry. Wszystko powinno mieć swoje miejsce. Dobrym pomysłem może być rozrysowanie sobie na kartce pewnych rzeczy, co się z czym wiąże (tylko i tak nie zaprojektujesz wszystkiego za pierwszym razem, na to nie licz nawet. Raczej chodzi o to, że kartka i długopis może być stymulacją dla wyobraźni i myślenia bardziej koncepcyjnego o kodzie, z lotu ptaka, a nie na poziomie funkcji i ifów).
trzeba to zrobić inaczej i DUPA.
Czy korzystasz z Git? Jeśli nie to powinieneś zacząć. Wtedy łatwo możesz cofać zmiany i masz ładny podgląd wszystkiego co po kolei robiłeś (pod warunkiem regularnego commitowania).
Nie wiem jak się zabrać za grę. Jak to powinno działać. Pisze coś a z perspektywy czasu okazuje się, że trzeba to przebudować.
Kiedy to przebuduje - trzeba zmienić coś innego. Kiedy wszystko jest zrobione, to dochodzą nowe funkcje i znów trzeba zmieniać!
Z czasem nauczysz się tworzyć skalowalne rozwiązania... :) Czasem kwestią jest też stosowanie odpowiednich wzorców projektowych.
Przy projektowaniu gier przydają się komunikaty/komendy. Polega to na tym, że obiekty w grze ("gracz", "żołnierz", "apteczka", "czołg") mogą nawzajem wysyłać do siebie komunikaty. Np. "gracz" może wysłać komunikat "bierz" do obiektu "apteczka", a obiekt "czołg" może wysłać komunikat "strzelaj" do obiektu "żołnierz" itp.
http://gameprogrammingpatterns.com/command.html
To wiele upraszcza w sytuacji, kiedy gra się rozrasta (bo masz gotowy protokół komunikacji między obiektami i system reagowania na zdarzenia. Więc jeśli dodajesz nowy rodzaj obiektu np. "robot", który ma strzelać to tylko wpinasz go w cały system, i pozwalasz żeby wysyłał komunikat "strzelaj", na który już będzie reszta obiektów sama reagować).
OOP jest też przydatne, szczególnie polimorfizm. W ten sposób możesz przypisać metodę AI
do każdego obiektu inną. I robot będzie miał inną sztuczną inteligencję niż żołnierz, a z perspektywy głównej pętli gry będzie to tak samo się obsługiwało. Mniej ifów, więcej abstrakcji.