Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

04.06.2005, 17:05

Problem mit Zeitzähler

Hallo Leute. Da ich im Moment ohne irgeneine Engine arbeite, muss ich mir den Zeitzähler (fNumSecsPassed) selbst erstellen. Das Problem ist, dass das Spiel dabei ziemlich ruckelt.
Hier mal ein Auszug aus WinMain:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
g_fTime=0.0f;
    g_fTimePassed=0.0f;
    g_fFrequency=0.0f;
    LONGLONG llStartTime,llEndTime,llFreq;
    QueryPerformanceFrequency((LARGE_INTEGER*)&llFreq);
    g_fFrequency=(float)llFreq;
    
    if (SUCCEEDED(g_pPacman->Init(hWnd)))
    { 
        ShowWindow(hWnd,SW_SHOWDEFAULT);
        UpdateWindow(hWnd);

        MSG msg; 
        while(msg.message!=WM_QUIT)
        {
            QueryPerformanceCounter((LARGE_INTEGER*)&llStartTime);
            if (PeekMessage(&msg,NULL,0U,0U,PM_REMOVE))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
            else g_pGame->Run();
            QueryPerformanceCounter((LARGE_INTEGER*)&llEndTime);
            float fElapsed=(float)(llEndTime-llStartTime);
            if(llEndTime == llStartTime) g_fTimePassed = 0.0001f;
            g_fTimePassed=fElapsed/g_fFrequency;
            //g_fTimePassed=fElapsed;

            g_fTime+=g_fTimePassed;
        }
    }


Und die Move-Methode von m_pGame:

C-/C++-Quelltext

1
2
3
4
5
6
7
if (GetAsyncKeyState(VK_LEFT)<0)    m_fCamAngle-=90.0f*D3DX_PI/180.0f*g_fTimePassed;
    if (GetAsyncKeyState(VK_RIGHT)<0)   m_fCamAngle+=90.0f*D3DX_PI/180.0f*g_fTimePassed;
    
    D3DXVECTOR3 vCamDir(sinf(m_fCamAngle),0.0f,cosf(m_fCamAngle));
    
    if (GetAsyncKeyState(VK_UP)<0)      vPos-=vCamDir;
    if (GetAsyncKeyState(VK_DOWN)<0)    vPos+=vCamDir;


Uch hoffe, ihr könnt mir helfen.
Mein Projekt: Rise of the Sylvan

DrthM2001

Alter Hase

Beiträge: 721

Wohnort: Karlsruhe

  • Private Nachricht senden

2

05.06.2005, 00:54

Ich kann jetzt deinen code nicht auf fehler untersuchen, weil ich grad nicht mehr weiß wie das so alles funktioniert. aber hier mal mein code, der leistet gute arbeit:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void GameClass::CalculateFrameRate()
{
    static float lastTime           = 0.0f;     // This will hold the time from the last frame

    static float Time = 0.0f;               // This stores the last frame's time

    static unsigned int FrameCounter= 0;

    float currentTime = timeGetTime() * 0.001f;             

    Game.FrameTime = currentTime - Time;

    if(Game.FrameTime<0)
        Game.FrameTime=-Game.FrameTime;


    Time = currentTime;
    FrameCounter++;

    if( currentTime - lastTime > 1.0f )
    {
        lastTime = currentTime;
        Game.FPS=FrameCounter;
        FrameCounter = 0;
    }
}


und die movefunktion dann:

C-/C++-Quelltext

1
Game.ActiveCamera->MoveCamera(-7.0f*Game.FrameTime);

3

05.06.2005, 11:08

Also bei Davids TriBase ist das in der MsgLoop und funktioniert. Aber bei mir ruckelt es irgendwie. Ich hab's mal mit timeGetTime versucht, das hat's aber irgendwie auch nicht gebracht.

[Edit]
Ich hätte die Zeit nur bei g_pGame->Run messen sollen und nicht noch TranslateMessage und DispatchMessage.
Aber bei der Rotation ruckelt's noch ein bisschen, während beim Laufen schon alles glatt geht.
(Sowohl mit timeGetTime als auch mit QueryPerformanceCounter).
Hat nicht jemand noch eine Idee.
Mein Projekt: Rise of the Sylvan

Osram

Alter Hase

Beiträge: 889

Wohnort: Weissenthurm

Beruf: SW Entwickler

  • Private Nachricht senden

4

05.06.2005, 16:05

Die beiden Hauptmöglichkeiten, warum es ruckeln kann sind:
- niedrige fps
- variierende fps

Die Zeit sollte nur einmal pro Frame bestimmt werden.

Schreib mal die FrameTimes in ein array und gib das bei Beenden in eine Datei aus und poste hier mal einen Abschnitt von sagen wir 50 frames, dann können wir mehr sagen. Am besten nimm MilliSekunden als Einheit.
"Games are algorithmic entertainment."

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

5

05.06.2005, 17:54

Ich habe da so eine Vermutung... kick mal alles was mit der Zeit zu tun hat raus. Wenn es dann noch ruckelt hängt es wohl damit zusammen, dass dein Spiel nur dann bewegt wird, wenn keinerlei Nachrichten in der Schlange sind.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

DrthM2001

Alter Hase

Beiträge: 721

Wohnort: Karlsruhe

  • Private Nachricht senden

6

05.06.2005, 18:00

C-/C++-Quelltext

1
2
3
4
5
6
if (PeekMessage(&msg,NULL,0U,0U,PM_REMOVE))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
            else g_pGame->Run(); 


diese passage halte ich für etwas unlogisch. ich glaube nox hat recht, wenn run deine renderfunktion ist.

koschka

Community-Fossil

Beiträge: 2 862

Wohnort: Dresden

Beruf: Student

  • Private Nachricht senden

7

05.06.2005, 20:39

Jep ich glaube auch und wenn nicht dann poste mal wies es Osram oben beschrieben hat :)

8

05.06.2005, 21:08

Also ich hab das mal wieder zu QueryPerformanceCounter umgeändert. Die FrameRates haben jedes Mal 0.046806. Dann hab ich es noch mal mit 1000 multipliziert und dann ergab das jedes mal 46.859383.

An variierenden FrameRates scheint's nicht zu liegen.

Ich weiß nicht, wie ich das beschreiben soll. Die Sprünge zwischen den einzelnen Frames sind vielleicht ziemlich groß oder so.
Mein Projekt: Rise of the Sylvan

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

9

06.06.2005, 14:16

46 Oo das ist ziemlcih wenig wenn man bedenkt, dass es nach jedem Nachrichtenverarbeiten einmal gemessen wird. Mach es so wie in der Tribase:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    while(!bQuit)
    {
        llStartTime=timeGetTime();

        // Nachrichten verarbeiten

        while(PeekMessage(&Message, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&Message);
            DispatchMessage(&Message);

            if(Message.message == WM_QUIT || Message.message == WM_DESTROY )
            {
                // Schleife verlassen!

                bQuit = TRUE;
            }
        }
        neu->move(dTime);
        neu->render();
        llEndTime=timeGetTime();
        dTime=((llEndTime-llStartTime)/1000.0);
    }
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

10

13.06.2005, 14:08

OK, das ist schon etwas besser aber ganz perfekt ist es immer nich nicht. Es ruckelt immer noch ein bisschen.
Mein Projekt: Rise of the Sylvan

Werbeanzeige