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

[SFML] Przetwarzanie czasu w grze

Ostatnio zmodyfikowano 2024-02-12 17:06
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
[SFML] Przetwarzanie czasu w grze
» 2024-02-12 15:50:15
Załóżmy, że mam obiekt Unit, który posiada zmienną timeOfPrevAction przechowującą informację o tym kiedy została wykonana poprzednia akcja. Jak aktualizować ten obiekt co 0.1s ??


C/C++
class Unit
{
public:
   
float x, y;
   
int timeOfPrevAction;
   
   
Unit();
   
~Unit();
   
void update();
};
P-180746
DejaVu
» 2024-02-12 15:56:22
Jednostki nie powinny zawierać informacji 'kiedy' ostatni raz była wykonana akcja. W grach stosuje się zazwyczaj 'stałą' deltę przyrostu czasu. Oznacza to, że poza jednostkami kontrolujesz czas i dbasz o to, aby np. 30x na sekundę w równych odstępach czasu była wywoływana metoda update(). Zamiast czasu możesz stosować 'ticki'. Tick to taka sztuczna jednostka, gdzie np. zakładasz, że logika gry aktualizuje się 30x na sekundę, czyli w ciągu 1 sekundy masz 30 ticków. Wówczas jeżeli jakieś zdarzenie trwa 45 ticków to wiesz, że po 45 wywołaniach metody Update ma np. skończyć się budować broń/jednostka lub np. ma się przeładować broń i być gotowa do kolejnego strzału. Mając ticki, wszystko kontrolujesz w liczbach całkowitych.

Jeżeli nie chcesz robić ticków, możesz przekazywać 'delta czasu' do metody 'update' ile upłynęło czasu w sekundach (typ double), ale obliczenia na double-ach to pchanie się w kłopoty, bo gdzieś będzie Ci uciekała precyzja obliczeń i prędzej czy później będziesz miał z tego powodu 'artefakty'.

Gdy zatrzymujesz czas, to po prostu przestajesz wywoływać metodę update() dla każdej jednostki, ale nadal logika 'pauzy' odbywa się poza jednostkami, tylko w klasie, która steruje czasem, a dokładniej 'kontroluje' w jakich odstępach czasu rzeczywistego należy wywołać metodę update, aby uzyskać mniej więcej 30 ticków/sek.
P-180747
tBane
Temat założony przez niniejszego użytkownika
» 2024-02-12 16:58:48
czyli zamiast stosować timeOfPrevAction  lepiej zastosować "liczniki akcji" ?

np. dla ataku:

C/C++
attackAction = 0.0f;
attackActionEndValue = 50.0f;

if( attackActions < attackActionEndValue )
{
   
attackAction += 1.0f;
} else
{
   
attackAction = 0.0f;
   
attack();
}
P-180748
DejaVu
» 2024-02-12 17:03:35
Nie używaj double. Użyj int-a lub ewentualnie uint64_t jeżeli uważasz, że int może być 'za mały'. Double jest podatny na błędy. Czyli:
C/C++
void Unit::update()
{
   
if( m_waitForWeaponRecharge > 0 )
       
 --m_waitForWeaponRecharge;
   
   
}

bool Unit::attack( Unit * target )
{
   
if( m_waitForWeaponRecharge > 0 )
       
 return false;
   
   
if( target == nullptr )
       
 return false;
   
   
if( !target->canBeAttacked() )
       
 return false;
   
   
target->dealDamage( 50 );
   
m_waitForWeaponRecharge = 10;
   
return true;
}
P-180749
tBane
Temat założony przez niniejszego użytkownika
» 2024-02-12 17:06:31
dzięki za pomoc! :-)
P-180750
« 1 »
  Strona 1 z 1