• Login

1

Wednesday, April 16th 2008, 7:39am

Wie löst ihr das Zeit Problem bei Spielen?

Hallo,
ich Programmiere gerade an einen java Game(J2ME und J2SE) und da kam die Frage auf wie löse ich, das das Spiel auf allen CPUs die gleiche Geschwindigkeit abspielt. Ihr wisst ja bei alten Dos Games gibt es immer so tolle Geschwindigkeits Probleme.

Meine Lösung Pseudo-Code:

int startzeit;
int endzeit;
int wartezeit=0; //Millisekunden

while(true)
{
startzeit=getTime();
game();
endzeit=getTime();
wartezeit=(endzeit-startzeit)*1000;
warte(wartezeit);
}

Nur die Frage ist das Optimal? Es gibt ja noch die möglichkeit das man die Zeit an die Bewegungsgeschwindigkeit anhängt.
Gamedev-Nation.org - Die freundliche Spieleentwickler Community

I am sick of it to be a beta nerd. So I have decided to become a alpha!

2

Wednesday, April 16th 2008, 5:44pm

Hiho!
In meinem Buch "3D -Spieleprogrammierung" (von David Scherfgen) die zweite Methode verwendet.
Aber ich verstehe deine Lösung eh nicht ganz: Du berechnest, wie lange game() braucht und lässt das Programm anschließend noch einmal um dieselbe Zeit warten. Dabei läuft das Spiel doch aber nicht auf jedem PC gleich schnell, jeder Schleifendurchlauf dauert nur doppelt so lange.

Jedenfalls hab ich es so gelernt:
Multipliziere die Zeit, die game() braucht (in Sekunden), mit der Bewegungsgeschwindigkeit.
Wenn nun game() z.B. 0.03 Sekunden dauert, wird das Spiel nur um 0.03 Sekunden bewegt.

Gruß
Eklipse
Bild

3

Wednesday, April 16th 2008, 6:46pm

Quoted

Multipliziere die Zeit, die game() braucht (in Sekunden), mit der Bewegungsgeschwindigkeit.
Wenn nun game() z.B. 0.03 Sekunden dauert, wird das Spiel nur um 0.03 Sekunden bewegt.
Genau so macht man es auch der professionellen Spieleprogrammierung (und nicht nur da, sonder bei allen Software-Entwicklungen, die irgendwie synchronisiert werden müssen). Von daher würde ich es auch so machen ;)

Und ja, DK, ich blick deinen Code auch nicht xD

Drag-On

4

Wednesday, April 16th 2008, 6:55pm

Ich bin kein Programmierer... aber ich kenne Zufällig zumindest eine Theoretische Methode...

Limitiere doch einfach die Framerate. In GTA zB ist ein Frame Limiter drin, der das Spiel auf konstant 30 Frames runterregelt. Dos-Spiele werden ja deshalb so schnell, weil die sowas nicht haben und die neue Hardware extreme Frameraten schafft...

BTW: Bin Noob und stolz darauf ;)

5

Wednesday, April 16th 2008, 8:17pm

Quoted

Multipliziere die Zeit, die game() braucht (in Sekunden), mit der Bewegungsgeschwindigkeit.
Wenn nun game() z.B. 0.03 Sekunden dauert, wird das Spiel nur um 0.03 Sekunden bewegt.
Genau so macht man es auch der professionellen Spieleprogrammierung (und nicht nur da, sonder bei allen Software-Entwicklungen, die irgendwie synchronisiert werden müssen). Von daher würde ich es auch so machen ;)

Und ja, DK, ich blick deinen Code auch nicht xD

Drag-On

Habe das gleiche Buch irgend wo rumstehen XD. 3d Spieleprogrammierung mit Direct X. Nur ich möchte es ja für ein 2D (RPG) machen.

@general:
Also ich rufe die repaint Anweisung immer nach der warte Funktion auf, hatte es im Pseudo-Code vergessen. Jedenfalls wäre es doch eine Art Frame Reduzierung die ich da gebaut habe oder nicht.
Gamedev-Nation.org - Die freundliche Spieleentwickler Community

I am sick of it to be a beta nerd. So I have decided to become a alpha!

6

Wednesday, April 16th 2008, 8:33pm

Ob nun 3D oder 2D, das grundlegende Prinzip bleibt ja gleich. ;)

Dass bei deiner Theorie die refresh-Funktion dann nach der warte-Funktion kommt, ändert leider nichts daran, dass es weiterhin auf verschiedenen Rechnern unterschiedlich läuft.
Beispiel:
game() dauert x Sekunden.
Dann verzögerst du mit warte das Spiel danach um x sekunden.
Letztendlich braucht das Spiel dann für einen Durchlauf 2*x bzw. 3*x Sekunden (game&warte). Da x aber rechnerabhängig ist, ist dein Problem nicht gelöst, das Spiel wird nur etwas verlangsamt.
Bild

7

Thursday, April 17th 2008, 3:53pm

Du solltest beides tun, die Framebeschränkung dient zur Schonung der CPU, weil sie sonst auf 100%(oder bei mehrkernen nur ein Kern auf 100%) läuft was dir der Spieler übel nehmen wird.
Alleine reicht das aber noch nicht, dass sicher gestellt ist, dass das SPiel überall gleich schnell läuft, du hast ja eine Begrenzung nach oben aber nicht nach unten, deswegen solltest du zusätzlich noch alle Ereignisse mit der vergangenen Zeit verrechnen,

8

Thursday, April 17th 2008, 4:33pm

Verzeihung, ich versteh hier was nich ganz, wills aber verstehen weil es sich interessant anhört ^^"

Was meint ihr mit dem Befehl game(); ?

9

Thursday, April 17th 2008, 4:46pm

Der Code des Games, sprich die Haupttschleife ist gemeint.
Es geht darum, dass in einem Spiel meistens eine Hauptschleife verwendet wird welche je nach CPU Geschwindigkeit unterschiedlich schnell abgehandelt werden würde. Wenn man nun in jedem Game() Durchlauf z.B. eine Figur um x Pixel vorbewegen würde, würde sie je nach CPU Geschwindigkeit unterschiedlich schnell vorwärts rücken, was nicht sein kann. (Ist bei manchen alten Spielen noch so, die rasen auf modernen PCs auf unspielbaren Geschwindigkeiten).
Die Frage war jetzt wie man dafür sorgen sollte, dass die Geschwindigkeiten immer gleich sind, mit einer Begrenzung der Framezahl oder indem man die vergangene Zeit verrechnet.
Meine Antwort war, beides ist notwendig, da die Begrenzung der Framezahl nur nach oben hin möglich ist und somit bei langsameren PCs in langsameren Spielbewegungen resultiert(auch wenn man auf max. 30 FPS beschränkt und dann 25 hat ist das fürs Auge noch problemlos spielbar, aber das Spiel läuft um 1/6 langsamer, außerdem auch noch unregelmäßig). Und bei einer Verrechnung alleine ohne Framebeschränkung die CPU sicher unerwünscht auf 100% laufen würde(oder eben ein Kern der CPU)

10

Thursday, April 17th 2008, 5:15pm

Ai, verstanden... ungefähr...
Danke ^^
Naja dann würde ich auch sagen die Framezahl muss nach oben hin beschränkt sein (nach unten geht doch garnich, dann läufts bei langsamen PCs garnicht O.o"), denn sonst hätte der Spieler garnichts von seinem schnellen Prozessor.
In der Methode ohne Framebeschränkung wird also immer der ganze Prozessor ausgelastet, egal wie schnell er ist, und das nur(!) um ein Spiel langsamer laufen zu lassen...
Aber jetz hab ich das Danke gesagt und nun werde ich mich hier raushalten vo.o (Aber trotzdem noch mitlesen wenn es die Zeit erlaubt xP)

Chaosgod Espér

Enchanted lord of Shadows

  • Send private message

11

Thursday, April 17th 2008, 11:25pm

sieht fast wie C aus... hmm
wenns fast gleich iss, kannste die Zeit der FPS auf allen rechnern mit

Source code

1
*time_step
auf allen rechnern gleich ablaufen lassen.

So läuft das Game auf langsamen rechnern dann zwar ruckelnd, aber er brauch für eine Aktion genauso lang wie wenn es flüssig läuft ( er überspringt dann diverse Dinge, daher ruckelts ).
There was a Cave,
below a Silent's Grave.
Tunnels, extending far, running wide,
going deep into the World on the other Side.
Poor little Child, that was to brave,
died painfully deep down, in the Devil's Cave.

Emi

Schlitzohr

Motto: router rip!

  • Send private message

12

Sunday, May 4th 2008, 10:30am

*hmmm*

Weißt du, seit ich mit dem Makern aufgehört habe, programmier ich auch in C# oder Java =O

und ich steh auch grad beim Synchronisationsproblem an. Wie wär es, wenn du einfach die Funktion anstann in einer Schleife immer mithilfe eines Timers aufruft? Das müsste in gewissen maßen helfen, aber na ja... sollte ein rechner so langsam sein, dass er es nicht in den dafür vorgesehenenen Intervallen schafft, kann man das auch vergessen =(

So wie Eklipse es sagt wär es wahrscheinlich am besten, auch, wenn es wahrscheinlich kompliziert ist ;-).

lg, Emi

13

Sunday, May 4th 2008, 12:24pm

Ob du nun in einer Schleife einen Timer hast und wartest oder ein anderes Timersystem nutzt ist doch grad das Selbe,
du kannst beides verwenden. Und wie schon gesagt die Variante von Eclipse löst zwar das Zeitproblem, aber du kriegst ne extrem hohe CPU Auslastung.
Den Timer verwendest du um die Framezahl nach oben hin zu limitieren und du verrechnest die Aktionen trotzdem mit der Zeit, damit es überall gleich läuft.

Social bookmarks