Richtige Spielschleife?


HEP

Member
Joined
Dec 25, 2006
Messages
188
Ich habe einige Probleme die Steuerung bei meinem neuen Spiel richtig hinzubekommen. Sie läuft irgendwie sehr - wie soll man sagen - "hakelig", und es kann eigentlich nur am Aufbau meiner Spielschleife liegen. Es kommt mir übrigens nur auf die Tastendrücke an und nicht - wie bei den meisten Spielen - auch auf das gedrückt halten. Ich dachte, ich stell einfach mal meine Spielschleife hier rein und vielleicht hat ja jemand Verbesserungsvorschläge:
Code:
<i>
</i>#define FRAMERATE 60
#define FRAMETIME 1000/FRAMERATE

while(running)
{
	if(SDL_PollEvent(&sdlevent))
	{
		if(sdlevent.type == SDL_JOYBUTTONDOWN)
			HandleInput(sdlevent.jbutton.button);
	}
	else
	{
		m_nCurrentTime = SDL_GetTicks();
		if(m_nCurrentTime > m_nNextFrame)
		{
			HandleAI();
			Render();
			m_nNextFrame = m_nCurrentTime + FRAMETIME;
		}
	}
}
 
ich bin mir nicht ganz sicher ob ich dich richtig verstanden habe, aber ich vermute mal du faehrst besser, wenn du sinngemaess folgendes machst:
Code:
<i>
</i>int buttonPressed=0;

while (1) {
   if(SDL_PollEvent(&sdlevent)) {
      if(sdlevent.type == SDL_JOYBUTTONDOWN) buttonPressed=1;
      if(sdlevent.type == SDL_JOYBUTTONUP) buttonPressed=0;
   }

   if (buttonPressed) doWateverYouWantToDoIfButtonHeldDown();
   handleAIAndOtherStuff();
}
 
Wie schon im Entwicklerchat angesprochen: Es kann sein, das dein Tastendruck mehrmals ausgefuehrt wird, ohne das ein Bild gezeichnet wird. Unwahrscheinlich (bei 60hz) aber dennoch moeglich. Ich wuerde bei einer solchen Schleife nur einen Event pro Bild abfangen.
 
HEP said:
Ich habe einige Probleme die Steuerung bei meinem neuen Spiel richtig hinzubekommen. Sie läuft irgendwie sehr - wie soll man sagen - "hakelig", und es kann eigentlich nur am Aufbau meiner Spielschleife liegen. Es kommt mir übrigens nur auf die Tastendrücke an und nicht - wie bei den meisten Spielen - auch auf das gedrückt halten. Ich dachte, ich stell einfach mal meine Spielschleife hier rein und vielleicht hat ja jemand Verbesserungsvorschläge:
Code:
<i>
</i>#define FRAMERATE 60
#define FRAMETIME 1000/FRAMERATE

while(running)
{
	if(SDL_PollEvent(&sdlevent))
	{
		if(sdlevent.type == SDL_JOYBUTTONDOWN)
			HandleInput(sdlevent.jbutton.button);
	}
	else
	{
		m_nCurrentTime = SDL_GetTicks();
		if(m_nCurrentTime > m_nNextFrame)
		{
			HandleAI();
			Render();
			m_nNextFrame = m_nCurrentTime + FRAMETIME;
		}
	}
}

Hallo,

bestimmt verpeil ich etwas..
führt dein Code zur Zeit nicht nur den HandleAI und Render Krams aus wenn du KEIN Input hast ? Wenn jetzt jemand wild die Knöpfe drückt wird deine AI nie etwas tun bzw nie etwas gerendert werden ?

Was den Input selbst angeht, das müßte korrekt sein, ein SDL_JOYBUTTUNDOWN wird nur erzeugt wenn der Knopf gedrückt wird, nicht wenn er festgehalten wird, allerdings wird durch das "if" beim PollEvent ja jetzt nur eine Eingabe pro "running" Schleifendurchgang bearbeitet.. drück man jetzt xmal schnell den Knopf.. dann hat man erstmal ein paar Eingaben in der Input Schleife.
Vielleicht wäre da ein "while" angebrachter um alle Eingaben zu bearbeiten, oder aber alle Events zu entfernen die nicht mit dem ersten if abgearbeitet werden, somit müßte das Programm reaktionschneller auf deine Eingaben sein.
 
Danke für die schnellen und zahlreichen Antworten! Ich habe alles ausprobiert, was mir ans Herz gelegt wurde, aber bei den meisten Vorschlägen konnte ich keinen Unterschied feststellen und bei G.o.D.'s Vorschlag kann man gar nicht steuern, weil der Cursor rasend schnell lief. Langsam glaube ich, dass das Problem an anderer Stelle liegt. Ich stehe aber vor dem Rätsel, welche Stelle das sein soll, da der Steuerungs-Code sehr überschaubar ist und ich keinen Fehler entdecken kann. Könnte es sein, dass der Stick einfach unpräzise ist oder die vier Zwischen-Richtungen (z.B. unten links) irgendwie speziell behandelt werden müssen? Was anderes kann ich mir eigentlich nicht mehr vorstellen.
 
Ich würde einen Timer benutzen...
Code:
<i>
</i>#define FRAMERATE 60
#define FRAMETIME 1000/FRAMERATE

int gametick()
{
    handleUserInput();     // Eventstapel auswerten
    updateAI();
    redraw();

    return FRAMETIME;
}

im Hauptprogramm:

{
    SDL_Timer* timer;

    timer = SDL_AddTimer ( FRAMETIME, gametick, NULL);

    // Ereignisschleife, bei Userevents dieses Event auf einem Stapel legen
    // wird aber erst beim Gametick ausgewertet
}

schau einfach mal hier:

http://de.wikibooks.org/wiki/SDL:_Timer
 
Back
Top