Tworzę platformówkę RPG dla jednego gracza w XNA 4.0. Chciałbym dodać zdolność, która sprawi, że czas „zatrzyma się” lub zwolni, i sprawi, że tylko postać gracza porusza się z oryginalną prędkością (podobną do zaklęcia Czas zatrzymania z serii Baldur's Gate). Nie szukam dokładnej implementacji, a raczej ogólnych pomysłów i wzorców projektowych.
EDYCJA: Dziękuję wszystkim za wspaniały wkład. Wymyśliłem następujące rozwiązanie
public void Update(GameTime gameTime)
{
GameTime newGameTime = new GameTime(gameTime.TotalGameTime,
new TimeSpan(gameTime.ElapsedGameTime.Ticks / DESIRED_TIME_MODIFIER));
gameTime = newGameTime;
lub coś podobnego. W ten sposób mogę ustawić inny czas dla komponentu odtwarzacza i inny dla reszty. Z pewnością nie jest wystarczająco uniwersalny, aby działać w grze, w której taki czas wypaczenia byłby centralnym elementem, ale mam nadzieję, że powinien on działać w tym przypadku. Nie podoba mi się to, że zaśmieca główną pętlę aktualizacji, ale z pewnością jest to najłatwiejszy sposób na jej wdrożenie. Myślę, że to w zasadzie to samo, co sugerował tesselode, więc dam mu zielony haczyk :)
źródło
Użycie czasu delta (milisekund, które upłynęły od ostatniej klatki) może nie wystarczyć do spowolnienia wrogów. Rzeczy takie jak szybkość ataku mogą być realizowane na podstawie czasu ostatniego ataku. Chociaż będzie spowalniać ruch, jeśli jest oparty na czasie, nie będzie spowalniał tempa ataku, rzucania zaklęć i innych efektów (regeneracja zdrowia, czas trwania efektów zaklęć) i tak dalej
Jeśli chcesz spowolnić dużą grupę elementów gry w grze dla jednego gracza, możesz stworzyć drugi zegar wewnętrzny dla każdego stworzenia, zegar rozpoczyna się w chwili, gdy pojawi się stworzenie. Kiedy rzucane jest wolne zaklęcie, każda klatka, zegar jest zwiększany o x% czasu, który faktycznie upłynął. Całe zachowanie potwora jest następnie określane przez jego wewnętrzny zegar. Jeśli różne potwory mają odporność na spowolnienie, mogą korzystać z własnego zegara, jest to w zasadzie liczba całkowita, która nie wymaga dużo miejsca ani obliczeń.
Kiedy efekt spowolnienia ustanie, zegary są nadal używane i są zwiększane o 100% czasu, który faktycznie upłynął.
Może to również działać w przypadku przyspieszenia zaklęć.
@ Sidar: Widzę dwie możliwości,
Zegar wewnętrzny na stworzenie. Aby dowiedzieć się, czy stwór jest gotowy do ponownego ataku: zapisz ostatnie użycie każdego ataku + czas doładowania i sprawdź, czy zegar wewnętrzny już minął.
Jeden licznik czasu na atak: wiesz, ile czasu zajmuje atak, aby się naładować, po prostu ustawiasz licznik czasu i odejmujesz czas, który upłynął * (1% spowolnienia) w każdej turze.
Ja osobiście wolę unikać odejmowania wielu pojedynczych timerów i użytkownika jednego wewnętrznego zegara, aby zaoszczędzić na czasie przetwarzania i złożoności.
To naprawdę zależy od preferencji (nie wpływa to tak bardzo na wydajność).
źródło
Możesz zacząć od prostego rozwiązania, takiego jak ujawnione przez tesselode lub Mr Beast. Ale jeśli zaczniesz mieszać złożone rzeczy, np. Czas pocisku, gdy rzucane jest zaklęcie spowolnienia, utkniesz.
Sugeruję wdrożenie hierarchii zegara :
Wszystko w twojej grze powinno wykorzystywać czasy delta z jednego zegara: efekty graficzne działają na zegarze GFX, AI i animacja działają na zegarze gry, stworzenia dotknięte zaklęciem spowolnienia działają na tymczasowym zegarze spowolnienia itp. Następnie różne rzeczy wpływa na różne części Twojej hierarchii: zaklęcie spowolnienia tworzy niestandardowy zegar i wpływa na niego, a czas na pocisk wpłynie na całą hierarchię zegara 3D.
źródło
Potrzebujesz tylko dwóch różnych zegarów zamiast jednego, jednego na czas odpowiedni dla rozgrywki i jednego „prawdziwego” czasu.
Następnie możesz po prostu zmienić gameSpeed, aby przyspieszyć (> 1) lub spowolnić czas (<1). Aby gracz poruszał się z inną prędkością, po prostu sprawdź, czy czas jest spowolniony, czy nie.
źródło