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

[SFML] Ruch gracza w grze

Ostatnio zmodyfikowano 2024-05-11 19:55
Autor Wiadomość
pekfos
» 2024-05-10 22:43:57
skoro tak, to dt nie jest deltą. Przynajmniej tak to rozumiem.
Nie chodzi o to czy jest, tylko o implementację obliczeń. Precyzja liczby zmiennoprzecinkowej zależy od jej wartości. Dla odpowiednio dużej liczby nie ma w ogóle części ułamkowej. Czas wciąż płynie, ale te floaty będą miały dokładność co do np pół sekundy, albo całej sekundy i wtedy delta będzie wynosić 0.5s albo 1s i zero w pozostałych obiegach pętli. sf::Time wewnętrznie trzyma czas jako liczbę całkowitą w mikrosekundach, więc nie ma tego problemu.

Więc jak wtedy aktualizować gracza ?
A co z kodem który podałem na to wcześniej?

C/C++
dt = currentTime.asSeconds() - prevTime.asSeconds();
Jak już to
C/C++
dt =( currentTime - prevTime ).asSeconds();
Chcesz mieć sf::Time minus sf::Time, a nie float minus float.
P-181054
tBane
Temat założony przez niniejszego użytkownika
» 2024-05-10 23:11:39
Ok, już rozumiem dlaczego należy używać sf::Time. Pozostało mi wyznaczyć aktualną klatkę animacji, ale przez to dt się gubię.

C/C++
sf::Clock clock;
sf::Time prevTime = clock.getElapsedTime();
sf::Time currentTime = prevTime;
float dt;

//...


while( window->isOpen() ) {
   
   
prevTime = currentTime;
   
currentTime = clock.getElapsedTime();
   
   
// ...
   
   
dt =( currentTime - prevTime ).asSeconds();
   
for( auto & go: gameObjects )
       
 go->update( dt );
   
// ...
   
P-181055
pekfos
» 2024-05-11 13:31:55
No to znowu, co z tym kodem który podałem? Masz tu symulację. Założyłem że animacja ma 12fps, zmienną fps w maine możesz kontrolować ile faktycznie aktualizacji na sekundę wykonujesz. Dla fps mniejszego od 12 będziesz czasem gubić klatki animacji, a dla większego czasem wyświetlać tą samą parę razy pod rząd, ale po 2 sekundach pracy będzie osiągnięte oczekiwane ~24 klatki w obu przypadkach.
C/C++
struct S
{
   
int step = 0;
   
float countdown = 0;
   
   
void update( float dt )
   
{
       
countdown -= dt;
       
while( countdown <= 0 )
       
{
           
countdown += 1.f / 12; // bo animacja ma np 12 klatek na sekundę tylko
           
step++;
           
// Logika związana ze step
       
}
    }
}
;

#include <cstdio>

int main()
{
   
S s;
   
int fps = 10;
   
float dt = 1.f / fps;
   
for( float t = 0; t < 2; t += dt )
   
{
       
printf( "t=%8.4fs, dt=%.4f, frame=%d\n", t, dt, s.step );
       
s.update( dt );
   
}
}
P-181056
tBane
Temat założony przez niniejszego użytkownika
» 2024-05-11 18:46:24
dobra, zrozumiałem. Przepisałem kod i wyszło mi coś takiego. Wszystko działa płynnie, dziękuję za pomoc :-)

C/C++
void calculateCurrentFrame( float dt ) {
   
countdown -= dt;
   
while( countdown <= 0.0f ) {
       
countdown += 1.0f / 12.0f; // 12 FPS
       
step += 1.0f;
   
}
   
}

void update( float dt ) {
   
   
float distance = 15.0f * stepSize * dt;
   
   
if( state == states::fight ) {
       
       
calculateCurrentFrame( dt );
       
       
if( step > 3.0f ) {
           
step -= float( step / 3 ) * 3.0f;
           
state = states::idle;
       
}
       
       
bodySprite->setTexture( * fightTextures[ direction * 4 + int( step ) ] );
   
}
   
else if( state == states::run ) {
       
       
calculateCurrentFrame( dt );
       
       
state = states::idle;
       
       
if( step > 3.0f )
           
 step -= float( step / 3 ) * 3.0f;
       
       
if( direction == 0 ) y -= distance;
       
       
if( direction == 1 ) x += distance;
       
       
if( direction == 2 ) y += distance;
       
       
if( direction == 3 ) x -= distance;
       
       
bodySprite->setTexture( * runTextures[ direction * 4 + int( step ) ] );
   
}
   
else if( state == states::idle ) {
       
       
calculateCurrentFrame( dt );
       
       
if( step > 3.0f )
           
 step -= float( step / 3 ) * 3.0f;
       
       
bodySprite->setTexture( * idleTextures[ direction * 4 + int( step ) ] );
       
   
}
   
   
mouseOvering();
   
   
bodySprite->setPosition( x, y );
   
collider->setPosition( x, y );
   
attackRangeArea->setPosition( x, y );
   
textname->setPosition( x, y - height - 30 );
   
   
}
P-181057
1 « 2 »
Poprzednia strona Strona 2 z 2