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

13.07.2006, 09:24

MainLoop || Code Design

Hi!

Und zwar ich hab da mal eine grundlegende Frage:

Wenn ich nun ein Spiel mach, wie sieht dann da eigentlich mein MainLoop aus? Auf was soll man achten, was gibts zu dem ganzen zu sagen?

Ich würd einfach gern mal ein paar Infos, tipps, Erfahrungen hören!

Besten Dank
Grüße Jürgen

koschka

Community-Fossil

Beiträge: 2 862

Wohnort: Dresden

Beruf: Student

  • Private Nachricht senden

2

13.07.2006, 11:42

da du ja ein Fenster hast, und damit auch eine "Fensterprozedur" kannst du einfach WM_PAINT abfragen. Dort schmeist du deine Render Funktion rein und ein ValidateRect(hWnd, NULL);
siehe hier -> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_9epg.asp

Hauptschleife:

C-/C++-Quelltext

1
2
3
4
5
while(1)
{
  Render(); // render something

  Move(); // move something, get input a.s.o.

};



Eingaben kann man mit WM_COMMAND holen. DInput braucht man erst ab Joysticks.

WM_PAINT abfangen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
{
    switch(uMsg)
    {
    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;
    case WM_PAINT:

        if(pD3DDevice)
        {
            Render();
            ValidateRect( hwnd, NULL );
        }
        return 0;

    };
    return ::DefWindowProcW(hwnd, uMsg, wParam, lParam);
}


*verschoben, da dies nichts mit dem Buch zu tun hat.

3

13.07.2006, 14:13

Ich mach immer eine Mainloop in der WinMain. Geht genauso.

Alternativ kannst du auch einen endlichen Automaten verwenden (funktioniert - wie in David's Buch - mit "Zuständen"). Damit soll man irgendwie das ALT+TAB Problem umgehen können...

Anonymous

unregistriert

4

13.07.2006, 18:29

koschka
Ähme, was hat WM_PAINT mit Direct3D zu tun? Irgendwie gar nichts. Direct3D hat eine höhere Instanz als GDI.

koschka

Community-Fossil

Beiträge: 2 862

Wohnort: Dresden

Beruf: Student

  • Private Nachricht senden

5

13.07.2006, 20:17

öhm, ja hab mich vllt. etwas unglücklich ausgedrückt, sollte eher so sein, das wenn WM_PAINT aufgerufen wird, dann Render aufgerufen werden soll

Anonymous

unregistriert

6

13.07.2006, 23:06

koschka
Das lohnt sich kein bisschen, daher kann man auf WM_PAINT verzichten, da das dortige Ergebnis sowieso durch die Hauptschleife "übermalt" wird.

Dazu ist es noch langsam! Denn wenn man das Fenster verschiebt, muß man einen Frame 2x rendern.

Das Gurke

Community-Fossil

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

7

13.07.2006, 23:49

Ich frag mich grad ob meine Version sinnig ist, ich geb sie mal zum Abschuss frei ^^ Es handelt sich dabei um KEIN Spiel sondern um eine Applikation die im Fenstermodus läuft, daher das Sleep. Das würde man bei nem Spiel eleganter lösen *g*

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
    // Und hüpfen in die Nachrichtenschleife   

    while(true)
    {
        // Haben wir eine Nachricht? Dann sofort bearbeiten

        // Peek Message liefert false wenn keine Nachricht vorliegt, remember ;)

        if(PeekMessageW(&myWindow->msg_,NULL,0,0,PM_REMOVE))
        {
            if(myWindow->msg_.message == WM_QUIT)
            {
                // Haben wir überhaupt ein Level geladen?

                if(Global::getInst()->Runtime_.bLevel == true)
                {
                   // Irrelevantes was bei WM_QUIT abläuft

                }
                    
            }

            TranslateMessage(&myWindow->msg_);
            DispatchMessageW(&myWindow->msg_);
        }
        // Keine Nachricht, wir haben also Rechenzeit frei

        else
        {
            Render::getInst()->renderFrame();
            Sleep(10);
        }

Osram

Alter Hase

Beiträge: 889

Wohnort: Weissenthurm

Beruf: SW Entwickler

  • Private Nachricht senden

8

14.07.2006, 11:38

Zitat von »"nix da"«


Das lohnt sich kein bisschen, daher kann man auf WM_PAINT verzichten, da das dortige Ergebnis sowieso durch die Hauptschleife "übermalt" wird.

Dazu ist es noch langsam! Denn wenn man das Fenster verschiebt, muß man einen Frame 2x rendern.


Natürlich ist die WM_PAINT Methode ein Ersatz für die "In Endlosschleife ständig Rendern" Methode, es wird also seltener gerendert. Sicher macht sie bei Ego Shootern wenig Sinn, aber es gibt ja z.B. auch 3D Puzzlespiele. Und bei Werkzeugen sollte man sich vor Begin des Implementierens auf jeden Fall die Frage stellen, welche von beiden Möglichkeiten man nun wählt. In meinem 3D Editor nehme ich übrigens die WM_PAINT Methode und das Hauptprogramm, was wir in meinem Tagesjob verkaufen, ein "durch die Küche lauf" Programm, haben wir es zumindest früher auch so gemacht (bin mir nicht ganz sicher ob das noch so ist).
"Games are algorithmic entertainment."

Anonymous

unregistriert

9

14.07.2006, 11:57

Ähm nur mal so nebenbei, ich kenn z.B. bei DDraw gar keine andere
Möglichkeit als WM_PAINT Oo , aber das sollte doch nicht so schlimm sein
bei einem kleinen 2D Jump&Run oder?!?

koschka

Community-Fossil

Beiträge: 2 862

Wohnort: Dresden

Beruf: Student

  • Private Nachricht senden

10

14.07.2006, 15:33

Jep natürlich geht es ohne -.- das while, nur mit dem WM_PAINT. Ich sehe gerade auch in der DXDoku ist es so gemacht.

Männer sind eben doch nicht multitrasink fähig ;)

Werbeanzeige