JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=16ec16d48ba64904a1e4255c0ac1ebf4Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Timing: Geht das so?
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
OLiver
Super JLI'ler


Alter: 33
Anmeldedatum: 29.06.2003
Beiträge: 306
Wohnort: Jena
Medaillen: Keine

BeitragVerfasst am: 15.09.2004, 13:15    Titel: Timing: Geht das so? Antworten mit Zitat

Rolling Eyes Hi,

ich habe mal eine grundlegende Frage zum Timing. Ich mache es immer so, ich habe eine "Timer"-Klasse:

Code:

class Timer
{
   unsigned timo;
   unsigned interval;

public:

   void Start(const int& intervall);
   bool Abgelaufen();
};

void Timer::Start(const int &intervall)
{
   timo=timeGetTime();
   interval=intervall;
}

bool Timer::Abgelaufen()
{
   if(timeGetTime()-timo>=interval)
   {
      timo=timeGetTime();
      return 1;
   }

   return 0;
}



Dort ruf ich dann Start auf (in diesem Fall 1 Millisekunde) und mach dann in der While Schleife beispielsweise:

[cpp]
if(timer.Abgelaufen()) x+=5;
[/cpp]

oder so.

Also soll er sich jede Millisekunde um 5 Pixel bewegen (nur so als Beispiel). Dann zeichne ich einfach alles und die Framerate kann mir egal sein. Kann man das so machen? Weil ich ja überall gelesen habe, dass man da irgendwie die Framerate einbeziehen muss etc... Ich habe nämlich jetzt das Problem, dass sich die Figur ziemlich ruckelig springt, fällt und bewegt, wenn ich die Timerabfrage wegmache, ist schön flüssig, aber das würde ja dann auf jeden Computer anders schnell laufen, was ich ja nicht will, also kann man das so machen oder muss man es ganz anders machen?
_________________
http://www.sieder25.org/ (Siedler 2 - Remake)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 15.09.2004, 13:24    Titel: Re: Timing: Geht das so? Antworten mit Zitat

OLiver hat Folgendes geschrieben:
Dann zeichne ich einfach alles und die Framerate kann mir egal sein.

Ganz so ist es nicht. Du solltest natürlich schon darauf achten, dass die Framerate im "normalen" Bereich bleibt. D.h., wenn du nicht genug Optimierungen anstellst/langsame Zeichenfunktionen verwendest, dann geht die Framerate ja trotzdem schnell in den Keller.

OLiver hat Folgendes geschrieben:
Ich habe nämlich jetzt das Problem, dass sich die Figur ziemlich ruckelig springt, fällt und bewegt, wenn ich die Timerabfrage wegmache

Ich mache es z.Z. auch so und bei mir funzt es flüssig...

Zeig doch mal den Code, in dem du die Timerklasse einsetzt. Vielleicht stimmt da was nicht ganz Wink
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
OLiver
Super JLI'ler


Alter: 33
Anmeldedatum: 29.06.2003
Beiträge: 306
Wohnort: Jena
Medaillen: Keine

BeitragVerfasst am: 15.09.2004, 13:38    Titel: Antworten mit Zitat

Es ist ein abgespeckte Version von Hazels Demoprogramm und es sieht ja auch ganz gut aus wie der springt, aber es ruckelt halt wie gesagt noch ziemlich dolle. Mad

Code:

#include <windows.h>
#include "os_spiele.h"
#include <string>


Direct3D d3d;
Tastatur tast;
HWND myhwnd;

Sprite figur;

bool jumps=0;
float jumppower=0;


// Koordinaten und die Geschwindigkeiten des Spielers
float x=500,y=0,sx=0,sy=0;

// Timer für Bewegungen

Timer moving;

// Tastenarray
bool tasten[256];

// Breite und Größe des Spielers
#define WIDTH 70
#define HEIGHT 70

const float GRAVITY    = .2f;      // Schwerkraft. Wird als Beschleunigungsfaktor verwendet
const float AIRCONTROL = 0.15f;      // Wieviel kontrolle über die Bewegung auf der X-Achse
                           // hat der Spieler, wenn er in der Luft ist(Beschleunigung)
const float JUMPPOWER  = 10.0f;      // Sprungkraft des Spielers

bool Stand();




LRESULT CALLBACK MessageHandler(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{

   switch(msg)
   {
   case WM_DESTROY:
      PostQuitMessage(0);
      return 0;
   case WM_KEYDOWN:
      switch(wParam)
      {
      case VK_ESCAPE:
         DestroyWindow(hwnd);
         break;
      }
      break;
   }

   return DefWindowProc(hwnd,msg,wParam,lParam);
}


int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
    WNDCLASSEX wc={
      sizeof(WNDCLASSEX),
      CS_HREDRAW|CS_VREDRAW,
      MessageHandler,
      0,
      0,
      hInstance,
      LoadIcon(NULL,IDI_WINLOGO),
      LoadCursor(NULL,IDC_ARROW),
      (HBRUSH)GetStockObject(WHITE_BRUSH),
      NULL,
      "WindowClass",
      LoadIcon(NULL,IDI_WINLOGO) };

   RegisterClassEx(&wc);

   myhwnd=CreateWindowEx(NULL,"WindowClass","Jumptest",WS_POPUP | WS_VISIBLE,0,0,1024,768,NULL,NULL,hInstance,NULL);


   if(!d3d.Create(myhwnd,1024,768,75))
      return 1;


   if(!tast.Create(hInstance,myhwnd))
      return 2;

   if(!d3d.CreateSprite("figur.png",70,70,figur,0xFFFF00FF))
      return 3;

   MSG msg;

   ShowCursor(0);
   moving.Start(1);

   while(msg.message!=WM_QUIT)
   {
      if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
      {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
      }
      else
      {
         // Tasten holen

         tast.GetDevice((LPVOID)&tasten);



         if(moving.Abgelaufen())
         {


         
            // Spieler bewegen
            y+=sy;

            // Wenn der Spieler sich in der Luft befindet
            if(!Stand())
            {
               // Schwerkraft wirken lassen
               sy+=GRAVITY;

            }

            // Wenn der Spieler fällt
            if(sy>0)
            {
               // ggf zum Stehen bringen
               if(Stand())
               {
                  sy=0;


               }
            }
            else if(!sy)
            {
               if(tasten[DIK_SPACE])
               {
                  jumps=1;
                  jumppower+=1;
                  if(jumppower==JUMPPOWER)
                  {
                     sy= -JUMPPOWER;
                     jumppower=0;
                     jumps=0;
                  }


               }
               else
               {
                  if(jumps)
                  {
                     sy= -jumppower;
                     jumppower=0;
                     jumps=0;
                  }

               }

            }
            // Nach rechts oder links laufen
            if(tasten[DIK_RIGHT])
               x+=5;
            if(tasten[DIK_LEFT])
               x-=5;
         }

      
         


         


         // Bildschrirmgrenzen einhalten

         if(x<0)
            x=0;
         else if(x+WIDTH>1024)
            x=1024-WIDTH;




         d3d.BeginScene();

         // Hintergrund mit Schwarz füllen
         d3d.FillBackBuffer(0xFF000000);

         d3d.DrawSprite(figur,x,y);

         d3d.EndScene();
         d3d.Present();
         
      }
   }


   return 0;
}



bool Stand()
{
   if(y+HEIGHT<768)
      return 0;
   else
   {
      y=768-HEIGHT;
      return 1;
   }

}
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 15.09.2004, 13:55    Titel: Re: Timing: Geht das so? Antworten mit Zitat

Mit dem Code scheint alles in Ordnung zu sein.
Allerdings bin ich mir gerade nicht sicher, ob das beim Kontruktor der Timer-Klasse so einfach geht, wenn du das als Referenz übergibst.
Die '1', die du übergibst, muss ja dauerhaft im Speicher sein, damit der Timer auf diese Adresse zugreifen kann.
Vielleicht musst du mal versuchen, das ohne Referenz zu machen:
OLiver hat Folgendes geschrieben:
Code:

class Timer
{
// [...]
   void Start(const int intervall);
};

void Timer::Start(const int intervall)
{
   timo=timeGetTime();
   interval=intervall;
}

_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
OLiver
Super JLI'ler


Alter: 33
Anmeldedatum: 29.06.2003
Beiträge: 306
Wohnort: Jena
Medaillen: Keine

BeitragVerfasst am: 15.09.2004, 14:07    Titel: Antworten mit Zitat

Hmm, das glaub ich nich, denn es wird ja nur als Referenz übergeben und gespeichert als normale Membervariable , die dann den Inhalt von der Referenz bekommt, ich denke schon, dass mit der Timerklasse alles in Ordnung ist, vielleicht is eine Millisekunde auch zu viel, dass es ruckelt, vielleicht muss es noch genauer werden? Ich weiß es nicht Crying or Very sad
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
MATTT
Junior JLI'ler



Anmeldedatum: 18.06.2003
Beiträge: 59

Medaillen: Keine

BeitragVerfasst am: 15.09.2004, 15:10    Titel: Antworten mit Zitat

Wenn du deine Timer auf 1 Millisekunde stellt und dein Computer schafft es nicht (und das tuht er auch auch nicht!) innerhalb 1 ms einen Frame zu generieren.
Ein Beispiel: Dein Spiel schafft eine Framerate von 90! Das wären
1s/90 = 1000ms/90 = 11.11111111...ms -> also mehr als 1 ms.

Die Lösung des Problems wäre, dass du einen höheren Intervall setzt.
Oder (noch besser) du machst es so:
Code:

x +=  (verstrichene_zeit_seit_letzte_mal / intervall) * geschindigkeit_pro_intervall;
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
PeaceKiller
JLI Master


Alter: 35
Anmeldedatum: 28.11.2002
Beiträge: 970

Medaillen: Keine

BeitragVerfasst am: 16.09.2004, 12:27    Titel: Antworten mit Zitat

Du kannst es ja auch mit meinem Timer versuchen der benützt den Performance Counter.

http://www.jliforum.de/board/viewtopic.php?t=2466
_________________
»If the automobile had followed the same development cycle as the computer, a Rolls-Royce would today cost $100, get a million miles per gallon, and explode once a year, killing everyone inside.«
– Robert X. Cringely, InfoWorld magazine
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
OLiver
Super JLI'ler


Alter: 33
Anmeldedatum: 29.06.2003
Beiträge: 306
Wohnort: Jena
Medaillen: Keine

BeitragVerfasst am: 16.09.2004, 14:48    Titel: Antworten mit Zitat

@MATTT:

Ja, ich weiß, dass er einen Frame nicht in einer Millisekunde darstellen kann, das Komische ist ja nur, dass, wenn ich die Timerabfrage wegmache es flüssig läuft, obwohl er ja eh nicht jede Millisekunde dort ankommt. Ich habe mal die 2 Programme hochgeladen, einmal mit und einmal ohne Timerabfrage (Springen mit Leertaste):



http://www.oliversseite.000k.net/jumping.rar
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
OLiver
Super JLI'ler


Alter: 33
Anmeldedatum: 29.06.2003
Beiträge: 306
Wohnort: Jena
Medaillen: Keine

BeitragVerfasst am: 16.09.2004, 16:17    Titel: Antworten mit Zitat

Komisch, wenn ich als Bildwiedherholungsfrequenz 60 statt 75 einstelle bewegt es sich flüssig? Question Question

Steckt da irgendeine Logik dahinter??? Confused
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 16.09.2004, 19:52    Titel: Antworten mit Zitat

Das klingt stark danach, dass vsync dahinter steckt.
Vielleicht funzt es wie gewünscht auch bei anderer Frequenz, wenn du es deaktivierst Wink
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
OLiver
Super JLI'ler


Alter: 33
Anmeldedatum: 29.06.2003
Beiträge: 306
Wohnort: Jena
Medaillen: Keine

BeitragVerfasst am: 17.09.2004, 12:20    Titel: Antworten mit Zitat

Dumme Frage aber was ist denn das? Question
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
OLiver
Super JLI'ler


Alter: 33
Anmeldedatum: 29.06.2003
Beiträge: 306
Wohnort: Jena
Medaillen: Keine

BeitragVerfasst am: 17.09.2004, 12:29    Titel: Antworten mit Zitat

Gut hat sich geklärt aber wie kann man das abstellen? Rolling Eyes
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
TheMillenium
Dark JLI'ler



Anmeldedatum: 21.07.2002
Beiträge: 1427
Wohnort: World
Medaillen: Keine

BeitragVerfasst am: 17.09.2004, 18:13    Titel: Antworten mit Zitat

Es soll da sowas wie Google.de geben!! Wink Razz

http://www.pc-magazin.de/common/page/page.php?table=pg&id=1202
_________________
The source of all power is in its destiny...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 17.09.2004, 19:34    Titel: Antworten mit Zitat

Entweder bei der DirectX initialisierung, oder beim anzeigen des Bildschirms (warten auf nächstes Bild, oder sofort anzeigen)

Ich würde auch die Variante aus dem zweiten Buch bevorzugen. Ohne Framebegrenzung oder so: Einfach die Zeit der letzten Frame messen und alle Bewegungen davon abhängig machen. Ungefähr so:

Position += 5*(Dauer der letzten Frame)

Dann ist es immer gleich schnell, egal wie viele Frames und eigentlich immer flüssig.
Einfach die Funktion der Systemzeit anschauen, am Anfang und am ENde der Frame messen und differenz ausrechnen.
_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 17.09.2004, 20:09    Titel: Antworten mit Zitat

Jonathan_Klein hat Folgendes geschrieben:
Ich würde auch die Variante aus dem zweiten Buch bevorzugen. Ohne Framebegrenzung oder so: Einfach die Zeit der letzten Frame messen und alle Bewegungen davon abhängig machen. Ungefähr so:

Position += 5*(Dauer der letzten Frame)

Dann ist es immer gleich schnell, egal wie viele Frames und eigentlich immer flüssig.
Einfach die Funktion der Systemzeit anschauen, am Anfang und am ENde der Frame messen und differenz ausrechnen.

Das hat allerdings (manchmal) einen kleinen Nachteil.
Dazu müsste man auf jeden Fall Fließkommavariablen benutzen.

Denn wenn du z.B. (bei einem 2D-Spiel) vorgesehen hast, ein Objekt alle 100 Millisekunden um einen Pixel zu bewegen, was machst du dann nach 50 Millisekunden?
Wink
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung Alle Zeiten sind GMT
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum