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

08.01.2009, 15:09

CPU-Auslastung

Hallo.
Ich habe mein erstes Spiel mit der SDL und C++ fast schon fertig. Es ist ein Tetrisklon.
Nun habe ich jedoch eine Frage:
Da der Spielablauf in einer Dauerschleife abläuft, ist auch die Prozessorauslastung dauerhaft auf 100%.
Wie kann man das vermeiden? Denn so viel Rechenleistung wird nun wirklich nicht für ein Tetris gebraucht.
Mir kam schon die Idee den Windowsspezifischen Befehl "Sleep()" zu benutzen, was jedoch bedeuten würde, dass es zu Verzögerungen in der Erkennung der Eingaben des Nutzers kommen würde.


mfg
Thunaer

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

2

08.01.2009, 15:21

Versuch mal Sleep(0).
@D13_Dreinig

3

08.01.2009, 15:24

Bzw. zeig mal den relevanten Code.
Könnte auch an GetMessage oder sowas in der Art liegen.
fka tm

4

08.01.2009, 15:26

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
while(done==0)
    {
        if(frame.KeyDown(SDLK_ESCAPE))
        {
            done=1;
        }
        if(frame.KeyDown(SDLK_UP))
        {
            if((SDL_GetTicks()-last)/250>=0.1){
                if(spielfeld.check_valid(m_block_now->get_next(), m_block_now->x, m_block_now->y, false))
                {
                    m_block_now->rotate();
                    last=SDL_GetTicks();
                }
            }
        }
        if(frame.KeyDown(SDLK_DOWN))
        {
            if((SDL_GetTicks()-lastdown)/100>=0.1){
                lastdown=SDL_GetTicks();
                tick=SDL_GetTicks();
                if(spielfeld.check_valid(&m_block_now->klotz[0][0], m_block_now->x, ((m_block_now->y)+1), true))
                {
                    m_block_now->y+=1;
                    if(m_block_now->y > 19)
                    { 
                        m_block_now->y=19;  
                    }
                }
            }
        }
        if(frame.KeyDown(SDLK_LEFT))
        {
            if((SDL_GetTicks()-last)/150>=0.1){
                last=SDL_GetTicks();
                if(spielfeld.check_valid(&m_block_now->klotz[0][0], ((m_block_now->x)-1), m_block_now->y, false))
                {
                    m_block_now->x-=1;
                    if(m_block_now->x<0)
                    {
                        m_block_now->x=0;
                    } 
                }
            }
        }
        if(frame.KeyDown(SDLK_RIGHT))
        {
            if((SDL_GetTicks()-last)/150>=0.1){
                last=SDL_GetTicks();
                if(spielfeld.check_valid(&m_block_now->klotz[0][0], ((m_block_now->x)+1), m_block_now->y, false))
                {
                    m_block_now->x+=1;
                }
            }
        }
        if(frame.KeyDown(SDLK_RCTRL))
        {
            if((SDL_GetTicks()-last)/100>=0.1){
                if(spielfeld.check_valid(&m_block_now->klotz[0][0], m_block_now->x, ((m_block_now->y)-1), false))
                {
                    last=SDL_GetTicks();
                    m_block_now->y-=1;
                }
            }
        }
        if((SDL_GetTicks()-tick)/speed>=0.1){
            tick=SDL_GetTicks();
            if(spielfeld.check_valid(&m_block_now->klotz[0][0], m_block_now->x, ((m_block_now->y)+1), true)&&(m_block_now->y < 20))
            {
                m_block_now->y+=1;
            }
            else
            {
                spielfeld.insert(&m_block_now->klotz[0][0], m_block_now->x, m_block_now->y, m_block_now->ID);
                /*spielfeld.checkrows(&reihen[0]);
                for(int z=0; z<4; z++)
                {
                    cout<<"reihen["<<z<<"]="<<reihen[z]<<"\n";
                } 
                spielfeld.delrows(reihen[0], reihen[1], reihen[2], reihen[3]);*/
                next_block();
            }
        }
        //m_klotz_img->SetPos(m_block_now->x, m_block_now->y);

        
        frame.Update();
        frame.Slock();
        background->Render(frame.GetScreen());
        show(frame.GetScreen(), &m_block_now->klotz[0][0], m_block_now->x, m_block_now->y, m_block_now->ID);
        show(frame.GetScreen(), &m_block_next->klotz[0][0], 13, 0, m_block_next->ID);
        spielfeld.show(frame.GetScreen());
        frame.Flip();
    }

5

08.01.2009, 15:32

Ja dann ist's klar, dass du 100% hast.
Würde die Message-Loop mit PeekMessage oä. realisieren.
fka tm

6

08.01.2009, 15:45

So weit ich weiß, wartet PeekMessage doch so lange bis eine Eingabe vom Nutzer kommt, oder nicht?
Denn das wäre nicht gut, da der Stein ja nach einer Weile automatisch runter kommen soll.

7

08.01.2009, 15:47

Neenee, das macht GetMessage.
fka tm

8

08.01.2009, 15:50

Könntest du mir denn vllt ein kleines Codebeispiel dazu geben?
Finde im Netz nicht so wirklich was, was auf meinen Fall passt...
Ich verstehe einfach nur nicht wie das ganze die Prozessorleistung reduzieren soll, da ich ja immernoch in einer Dauerschleife bleiben muss, um zu wissen wann der Stein ein Stück runter muss.


Tut mir leid wenn ich grade zu dumm bin um das zu verstehen :-D

9

08.01.2009, 15:57

Dann hätte jedes andere Spiel ja auch 100% Auslastung?

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
MSG msg;
while(msg.message != WM_QUIT)
{
    if(PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
    {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
    }
    else
       {    
         DeineSpielFunktion();
       }
}


In der WinProc die Ereignisse abfragen (case WM_KEYDOWN etc.).
fka tm

10

08.01.2009, 16:29

Jetzt hab ich meine Schleife so:

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
31
32
33
34
35
36
37
while(msg.message != WM_QUIT) 
    {
        if(PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
        {
                TranslateMessage( &msg );
                DispatchMessage( &msg );
        }
        else
        { 
            if((SDL_GetTicks()-tick)/speed>=0.1){
                tick=SDL_GetTicks();
                if(spielfeld.check_valid(&m_block_now->klotz[0][0], m_block_now->x, ((m_block_now->y)+1), true)&&(m_block_now->y < 20))
                {
                    m_block_now->y+=1;
                }
                else
                {
                    spielfeld.insert(&m_block_now->klotz[0][0], m_block_now->x, m_block_now->y, m_block_now->ID);
                    /*spielfeld.checkrows(&reihen[0]);
                    for(int z=0; z<4; z++)
                    {
                        cout<<"reihen["<<z<<"]="<<reihen[z]<<"\n";
                    } 
                    spielfeld.delrows(reihen[0], reihen[1], reihen[2], reihen[3]);*/
                    next_block();
                }
            }
            //m_klotz_img->SetPos(m_block_now->x, m_block_now->y);

            
            frame.Update();
            frame.Slock();
            background->Render(frame.GetScreen());
            show(frame.GetScreen(), &m_block_now->klotz[0][0], m_block_now->x, m_block_now->y, m_block_now->ID);
            show(frame.GetScreen(), &m_block_next->klotz[0][0], 13, 0, m_block_next->ID);
            spielfeld.show(frame.GetScreen());
            frame.Flip();
        }


Und es verbraucht trotzdem noch 100%...
Ich würde schätzen, dass es an dem else liegt...


Edit:
Da hier eben noch ein Post stand, dass ich die SuFu benutzen soll, da es die Frage schonmal gab, hier die Themen die ich dazu gefunden habe:
https://www.spieleprogrammierer.de/phpBB2/viewtopic.php?t=463&highlight=cpu
https://www.spieleprogrammierer.de/phpBB2/viewtopic.php?t=1810&highlight=cpu

Und diese Threads bringen mich nicht weiter....

Werbeanzeige