Einzelnen Beitrag anzeigen

teebee

Registriert seit: 17. Jan 2003
Ort: Köln
460 Beiträge
 
Delphi 6 Professional
 
#2

Re: NONVCL: Suche Spieleschleife / Programmrumpf

  Alt 16. Dez 2003, 13:13
Hallo,

zuerstmal stellt sich die Frage, ob Du bei Deinem Spiel die höchstmögliche Framerate haben möchtest - sprich: in jeder Idle-Phase wird der Bildschirm upgedatet - oder ob es ein Timer auch tut. Nachteil der ersten Variante: die Prozessorauslautung geht ans Limit, aber wenn man spielen will, dann ist das ja eigentlich auch ok, Vorteil ist eben eine höhe Framerate und damit ein flüssigerer Spielablauf. Bei einem Tetris, wo die Bewegungen der Steine ja eigentlich sowieso etwas abgehackt sind, kann man das ganze auch mit einem Timer machen. Sieht bei meinem Tetris jedenfalls sehr ordentlich aus.

Habe mal aus einem meiner Projekte was kopiert:

Zuerst die Nachrichtenschleife, man kann wählen ob mit Timer(RHighest=0) oder mit höchstmöglicher Framerate(RHighest=1), die entsprechende Schleife wird benutzt:
Delphi-Quellcode:
If (RHighest=1) Then Begin // nur wenn höchstmögliche Framerate gewünscht ist
  While Not(Beenden) Do Begin
   While PeekMessage(Message,0,0,0,PM_REMOVE) Do Begin
    TranslateMessage(Message);
    DispatchMessage(Message);
   End;
   // keine Nachrichten mehr, Zeit zum Rendern...
   Render;
  End;
 End
 Else Begin // andere Schleife wenn Timer ausreicht
  Timer := SetTimer(hWnd,0,50,Nil); // wenn hier das Intervall zu kurz ist, geht die Auslastung auch hoch
   While GetMessage(Message,0,0,0) Do begin
    TranslateMessage(Message);
    DispatchMessage(Message);
   End;
   KillTimer(hWnd,Timer);
 End;
In der WndProc sieht es dann so aus, Tastaturabfragen müsstest Du noch selbst abfragen:
Delphi-Quellcode:
Function WndProc(hWnd : Integer; Message, wParam, lParam: LongInt): LongInt; stdcall;
Begin
 Result := 0;
 case Message of
  WM_DESTROY: Begin
               PostQuitMessage(0);
              End;

  WM_CLOSE: Begin
             Beenden := True;
             DestroyWindow(hWnd);
            End;

  WM_TIMER: Render; // wenn Timer gewählt ist, wird hier in die Render-Funktion gegangen

  Else Result := DefWindowProc(hWnd, Message, wParam, lParam);
 End;
End;
In der Render-Funktion kannst du mit GetTickCount die Zeit messen, die seit dem letzten Frame vergangen ist und entsprechend der Geschwindigkeit der Steine diese bewegen.

Gruß, teebee
  Mit Zitat antworten Zitat