Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi NONVCL: Suche Spieleschleife / Programmrumpf (https://www.delphipraxis.net/13322-nonvcl-suche-spieleschleife-programmrumpf.html)

OLLI_T 16. Dez 2003 10:33


NONVCL: Suche Spieleschleife / Programmrumpf
 
Hallo Delphi Gemeinde!

Ich möchte gern zur geistigen Erbauung ein kleines NONVCL Tetris im Style vom guten alten Supertetris programmieren. Das ganz soll auf der Basis von profanen Bitmaps und nicht mit DirectX oder OpenGL laufen.

Nun stellt sich mir die Frage nach der besten Vorgehensweise, was Timer und Tastaturabfrage angeht. Der Rest ist dann eigentlich Standard.
Mir sind einige Ansätze bekannt, wie ich eine konstante Zeitbasis zum Bewegen der Teile bekomme. Aber mich würde einfach interessieren, wie ihr so an die Sache rangeht. Deshalb mach ich es wie bei der Zuschauerfrage bei "Wer wird Milliadär" und laß meinen Code ganz außen vor.

Bedanke mich schon jetzt für Eure Beiträge

Viele Grüsse

OLLI

teebee 16. Dez 2003 12:13

Re: NONVCL: Suche Spieleschleife / Programmrumpf
 
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

OLLI_T 16. Dez 2003 14:36

Re: NONVCL: Suche Spieleschleife / Programmrumpf
 
Hallo teebee!

Vielen Dank für Deine ausführliche Antwort! Werde also zunächst den Multimedia-Timer aus MMSystems als Zeitgeber einsetzen. Es wird ja nicht immer der gesamte Screen neu gezeichnet sondern nur der Bereich, auf dem sich was geändert hat.

Die sofortige Reaktion des Spieles auf die Tastendrucke ist mir allerdings sehr sehr wichtig. Arbeitest Du in Deiner Tetris Variante mit WM_KEYDOWN oder nutzt Du GetAsyncKeyState zur Tastaturabfrage. Wie sieht es mit entprellen aus? Muss ich mich darum kümmern oder kann ich einfach jedes WM_KEYDOWN direkt verarbeiten?

Viele Grüsse

OLLI

teebee 17. Dez 2003 08:38

Re: NONVCL: Suche Spieleschleife / Programmrumpf
 
Hallo OLLI,
Zitat:

Zitat von OLLI_T
Werde also zunächst den Multimedia-Timer aus MMSystems als Zeitgeber einsetzen.

Ich habe nur den normalen Timer verwendet, hat gereicht, aber warum nicht...
Zitat:

Die sofortige Reaktion des Spieles auf die Tastendrucke ist mir allerdings sehr sehr wichtig. Arbeitest Du in Deiner Tetris Variante mit WM_KEYDOWN oder nutzt Du GetAsyncKeyState zur Tastaturabfrage. Wie sieht es mit entprellen aus? Muss ich mich darum kümmern oder kann ich einfach jedes WM_KEYDOWN direkt verarbeiten?
Mit der Reaktion auf die Tasten ist es normalerweise gar kein Problem. Um das Entprellen musst Du Dich nicht kümmern, das findet schon in der Tastatur selbst und spätestens im Treiber statt. Ich habe bei meiner Variante (übrigens VCL) einfach im OnKeyDown-Ereignis (analog zu WM_KEYDOWN) auf die Steuertasten geprüft und dann direkt dort den Spielstein nach links/rechts/unten bewegt bzw. rotiert. Timergesteuert ist nur die automatische Bewegung nach unten.

Gruß, teebee

teebee 17. Dez 2003 08:38

Re: NONVCL: Suche Spieleschleife / Programmrumpf
 
Sorry, versehentliches Doppelposting...

OLLI_T 18. Dez 2003 19:07

Re: NONVCL: Suche Spieleschleife / Programmrumpf
 
Hallo Teebee!

Hab erst jetzt gesehen, dass Du mir geantwortet hast.

Danke Dir für Deine konstruktiven Hinweise. :thuimb:

Viele Grüsse

OLLI


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:17 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz