EatTheBlocks

Präsentation und Organisation von eigenen Projekten
Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: EatTheBlocks

Beitrag von fat-lobyte » Fr Feb 13, 2009 11:36 am

dani93 hat geschrieben:Normalerweise lösche ich immer die alte Version. Dieses mal hab ich sie aber on gelassen. Versionen hab ich mit 0.1 angefangen und ich bin inzwischen bei 0.2 (wie man auch im Menü rechts unten sieht). Das EatTheBlocks2 sollte nur zeigen, dass da was anderes drin ist. War vielleicht unglücklich gewählt...
Es ist keine echte neue Version sondern einfach ein Versuch das Spiel komplett anders aufzubauen.
Löschen solltest du deine alten Versionen auch nicht, schließlich könnte da ja noch guter Code drinnen sein. Dagegen dass es zu unordentlich wird gibts eben SVN.
dani93 hat geschrieben:Als svn.proggen.org ist zurzeit noch down. Lokal? Wie du meinst das direkt über mich gedownloaded wird? Das würde mich nicht stören... aber meine und auch die Downloadgeschwindigkeit des Spiels wären wahrscheinlich ziemlich niedrig.
Vielleicht mach ich auch meine alte Homepage wieder auf.
Nein nicht so ganz... Eine Homepage läuft auf einem Webserver, ein SVN Repository auf einem SVN-server. Deswegen kannst du kein Repository auf einer Homepage aufstellen. Lokal heißt, dass du es nicht öffentlich zugänglich ist. Du kannst es aber nur für die Versionierung verwenden, und wenns dann mal einen SVN Server gibt kannst du ganz leicht dein lokales Repository auf das Öffentliche spiegeln.
dani93 hat geschrieben:großer Weg * wenige FPS ~ kleiner Weg * viele FPS

Nur variiert dann der zurückgelegte Weg pro Frame. Und dann bekommt ich die regelmäßigen Bewegungen nicht mehr hin.

Ich weiß nicht inwieweit du diesen Thread jetzt gelesen hast, aber wir haben hier schon ein bisschen über die Möglichkeiten dieses Problem zu lösen diskutiert.
Na gut, so genau hab ichs nicht gelesen. Aber irgendwie sollte das doch möglich sein, oder?
Wie wärs wenn du deine Geschwindigkeit mitteln würdest? Nen kleinen Circular buffer, von dem in jedem (oder jedem 3.) Frame der Mittelwert berechnet wird, und so die geschwindigkeit neu gesetzt. Keine Ahnung, ist nur so ne Idee. (Wieder Frage an unsere Game- Profis).
Mir kommt das nur etwas spanisch vor, dass das unmöglich sein soll, verstehst du was ich meine?
dani93 hat geschrieben:Ich kenn mich mit diesem ganzen Lizenzkram nicht aus...
Macht nix, ich auch nicht. Ich glaube sogar die wenigsten Programmierer kennen sich damit aus. Umso wichtiger ist es, dass du eine Lizenz verwendest die von Anwälten geschrieben, gut durchdacht und bereits weit verbreitet und gut "getestet" ist. *ähem*GPL*ähem* ;-)
Haters gonna hate, potatoes gonna potate.

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: EatTheBlocks

Beitrag von nufan » Fr Feb 13, 2009 12:01 pm

fat-lobyte hat geschrieben:Nein nicht so ganz... Eine Homepage läuft auf einem Webserver, ein SVN Repository auf einem SVN-server.
Ich meinte auch nicht, dass ich SVN über meine Homepage laufen lassen will, sondern auf der Homepage unabhängig von SVN ein paar Downloads anzubieten. :)
Wie du vielleicht schon unter HELP gesehen hast, habe ich auch einen Sourceforge-Account. Vielleicht lade ich das auch mal dort hoch.
fat-lobyte hat geschrieben:Mir kommt das nur etwas spanisch vor, dass das unmöglich sein soll, verstehst du was ich meine?
Ich sage nicht, dass es unmöglich ist. Nur das ich es bis jetzt noch nicht geschafft habe.
fat-lobyte hat geschrieben:
dani93 hat geschrieben:Ich kenn mich mit diesem ganzen Lizenzkram nicht aus...
Macht nix, ich auch nicht. Ich glaube sogar die wenigsten Programmierer kennen sich damit aus. Umso wichtiger ist es, dass du eine Lizenz verwendest die von Anwälten geschrieben, gut durchdacht und bereits weit verbreitet und gut "getestet" ist. *ähem*GPL*ähem* ;-)
Hört sich nicht schlecht an...
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Das sagt schon ziemlich genau was ich meine :)

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: EatTheBlocks

Beitrag von Kerli » Fr Feb 13, 2009 1:49 pm

fat-lobyte hat geschrieben:
dani93 hat geschrieben:großer Weg * wenige FPS ~ kleiner Weg * viele FPS

Nur variiert dann der zurückgelegte Weg pro Frame. Und dann bekommt ich die regelmäßigen Bewegungen nicht mehr hin.

Ich weiß nicht inwieweit du diesen Thread jetzt gelesen hast, aber wir haben hier schon ein bisschen über die Möglichkeiten dieses Problem zu lösen diskutiert.
Na gut, so genau hab ichs nicht gelesen. Aber irgendwie sollte das doch möglich sein, oder?
Wie wärs wenn du deine Geschwindigkeit mitteln würdest? Nen kleinen Circular buffer, von dem in jedem (oder jedem 3.) Frame der Mittelwert berechnet wird, und so die geschwindigkeit neu gesetzt. Keine Ahnung, ist nur so ne Idee. (Wieder Frage an unsere Game- Profis).
Mir kommt das nur etwas spanisch vor, dass das unmöglich sein soll, verstehst du was ich meine?
Ich glaub das hab ich eh schon einmal gesagt. Du musst immer möglichst genau die Zeit des gerade vergangenen Frames messen und diese Zeit für die Bewegung im nächsten Frame verwenden. Sollte ein Frame kürzer als eine bestimmte Zeit dauern, dann legst du den Prozess einfach die restliche Zeit schlafen.

So erreichst du erstens ein gleich schnelle Bewegung unabhängig von der Geschwindigkeit des Computers, und die Framerate wird nach oben beschränkt.
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: EatTheBlocks

Beitrag von nufan » Fr Feb 13, 2009 3:51 pm

Sorry, ich steht gerade total auf der Leitung. Seit 5 Minuten starre ich auf deinen Beitrag und verstehs irgendwie nicht...

Mal jeden Teil einzeln:
Kerli hat geschrieben:Du musst immer möglichst genau die Zeit des gerade vergangenen Frames messen
Ok, das sollte kein Problem sein. Am Beginn GetTicks und am Ende, Differenz bilden und einer Variable zuweisen.
Kerli hat geschrieben:und diese Zeit für die Bewegung im nächsten Frame verwenden.
Als was? Maximalzeit? Zur Berechnung des Weges? Das verwirrt mich ein bisschen...
Kerli hat geschrieben:Sollte ein Frame kürzer als eine bestimmte Zeit dauern, dann legst du den Prozess einfach die restliche Zeit schlafen.
Ja, das mach ich jetzt auch schon. Und diese "bestimmte Zeit" ist bei mir vom Level abhängig.

Ich weiß, dass ich anstrengend bin ^^

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: EatTheBlocks

Beitrag von Kerli » Fr Feb 13, 2009 4:25 pm

dani93 hat geschrieben:Sorry, ich steht gerade total auf der Leitung. Seit 5 Minuten starre ich auf deinen Beitrag und verstehs irgendwie nicht...
Ok, dann einmal in Pseudocode:

Code: Alles auswählen

void move( float frametime )
{
  ob.x += frametime * move.x;
  ob.y += frametime * move.y;
}

frametime = 0;
while(run)
{
  start = getTime();
  
    render();
    move(frametime);

  frametime = getTime() - start;

  if( frametime < max_fps_frametime )
    sleep( max_fps_frametime - frametime );

  frametime = getTime() - start;
}
dani93 hat geschrieben: Mal jeden Teil einzeln:
Kerli hat geschrieben:Du musst immer möglichst genau die Zeit des gerade vergangenen Frames messen
Ok, das sollte kein Problem sein. Am Beginn GetTicks und am Ende, Differenz bilden und einer Variable zuweisen.
Kerli hat geschrieben:und diese Zeit für die Bewegung im nächsten Frame verwenden.
Als was? Maximalzeit? Zur Berechnung des Weges? Das verwirrt mich ein bisschen...
Die Zeit verwendest du zur Berechnung des Weges. Du hast einfach den Weg den du in einer Sekunde zurücklegen willst in zb einer 'move'-Variablen und multiplizierst die dann mit der wirklichen Zeit und addierst das zur aktuellen Position. Wenn ein Frame jetzt zum Beispiel eine halbe Sekunde dauert dann multiplizierst du die 'move'-Variable eben mit 0.5 und hast dann die korrekte Bewegung einer halben Sekunde.
dani93 hat geschrieben:
Kerli hat geschrieben:Sollte ein Frame kürzer als eine bestimmte Zeit dauern, dann legst du den Prozess einfach die restliche Zeit schlafen.
Ja, das mach ich jetzt auch schon. Und diese "bestimmte Zeit" ist bei mir vom Level abhängig.
Sollte es aber nicht. Was hat denn die maximale Framerate mit dem Level zu tun? Die sollte überall gleich sein. Für 60 FPS könntest du zb. eine Zeit von 1/60 Sekunden pro Frame nehmen.
dani93 hat geschrieben:Ich weiß, dass ich anstrengend bin ^^
Solange man erkennen kann das du dich damit beschäftigst und die Fragen einigermaßen verständlich sind geht das ja ;)
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: EatTheBlocks

Beitrag von nufan » Fr Feb 13, 2009 8:21 pm

Kerli hat geschrieben:Ok, dann einmal in Pseudocode:

Code: Alles auswählen

    void move( float frametime )
    {
      ob.x += frametime * move.x;
      ob.y += frametime * move.y;
    }

    frametime = 0;
    while(run)
    {
      start = getTime();
     
        render();
        move(frametime);

      frametime = getTime() - start;

      if( frametime < max_fps_frametime )
        sleep( max_fps_frametime - frametime );

      frametime = getTime() - start;
    }
LOL während ich gerade noch eine Frage dazu stellen wollte, hatte ich einen Geistesblitz :D
Nur gibts da das selbe Problem wie bei meinem Code (wenn ich das richtig verstanden habe):
Wenn ein Frame länger dauert als "max_fps_frametime", bekommt "frametime" nicht den gewohnten Wert und die Bewegung wird unregelmäßig. In dem Bruchteil einer Sekunde wird vielleicht der verhältnismäßig gleiche Weg zurückgelegt, aber trotzdem ist die Schlange dann nicht mehr in einem "Gitter".
Kerli hat geschrieben:Was hat denn die maximale Framerate mit dem Level zu tun? Die sollte überall gleich sein. Für 60 FPS könntest du zb. eine Zeit von 1/60 Sekunden pro Frame nehmen.
Ich weiß nicht, ob du dir den Code angesehen hast. Die Schlange bewegt sich konstant mit 10 Pixel pro Frame. Je höher das Level, desto kürzer die Zeit zwischen den Frames, desto schneller bewegt sich die Schlange.
So sieht die Schleife aus:

Code: Alles auswählen

  while (run)                                                                                       // run until something happens that "run" is changed
  {
  
    start = SDL_GetTicks ();                                                                        // get starting time of the frame
  
    check_events (&run);                                                                            // check for SDL events
  
    rendering ();                                                                                   // render background, fruit and snake
 
    check_border_score (&run, &score);                                                              // check if the snake hit a border are ate a fruit

    save_locations ();                                                                              // save the coordinations of the snake
 
    move_snake ();                                                                                  // the snake gets a new position

  
    if (run == -1)                                                                                  // user clicked "close"
    {
  
      deletesnake ();                                                                               // delete the snake
  
      exit (0);                                                                                     // quit game
  
    }
   
    end = SDL_GetTicks ();                                                                          // ending time of the frame
    
    if (end - start < 1000 / (level * 5))                                                           // check if frame was done too fast
      SDL_Delay ((1000 / (level * 5)) - (end - start));                                             // wait until the frame took enough time

  }
5 ist nur ein Wert um am Anfang auf eine langsame Geschwindigkeit zu kommen.
Kerli hat geschrieben:Solange man erkennen kann das du dich damit beschäftigst und die Fragen einigermaßen verständlich sind geht das ja ;)
Ich hätte deinen Code auch einfach kopieren können. Nur ich denke das ist wichtig und deswegen will ich es auch verstehen.

Ich hoffe, dass ich jetzt nicht allzu großen Blödsinn geschrieben habe. :)

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: EatTheBlocks

Beitrag von fat-lobyte » Fr Feb 13, 2009 9:02 pm

dani93 hat geschrieben:LOL während ich gerade noch eine Frage dazu stellen wollte, hatte ich einen Geistesblitz :D
Nur gibts da das selbe Problem wie bei meinem Code (wenn ich das richtig verstanden habe):
Wenn ein Frame länger dauert als "max_fps_frametime", bekommt "frametime" nicht den gewohnten Wert und die Bewegung wird unregelmäßig.
Was heißt "gewohnter Wert"? Wenn ein frame länger dauert als max_fps_frametime, dann nimmst du einfach die Zeit die der letzte Frame gebraucht hat (unter der annahme dass der jetzige Frame genausolang brauchen wird) und multiplizierst diese Zeit damit, ist doch nicht so kompliziert,oder? Wenn deine Framerate hin und her springt kommst du nicht drumrum, dass es ruckelt. So viel vertrauen in den Rechner muss sein.
dani93 hat geschrieben:In dem Bruchteil einer Sekunde wird vielleicht der verhältnismäßig gleiche Weg zurückgelegt, aber trotzdem ist die Schlange dann nicht mehr in einem "Gitter".
Wieso denn nicht? Wieso speicherst du die Position der Schlange nicht kontinuirlich in einem float ab, und veränderst diese auch korrekt mit der Zeit.
Das zurückrechnen ins "Gitter" ist dein geringstes Problem, das kannst du immer noch jedes mal dort machen wenn der Wert gebraucht wird, z.B. in der Move und Render Funktion. Das ist eine einfache Operation: %. Oder Wenn du deine Pixel in einem int speicherst brauchst du überhaupt keine Operation, sondern nur "position_discr = position_cont;", und der compiler erledigt dein Gitter für dich.

dani93 hat geschrieben:Ich weiß nicht, ob du dir den Code angesehen hast. Die Schlange bewegt sich konstant mit 10 Pixel pro Frame.
Ich glaub langsam kommen wir dem Problem näher:
Wieso bewegt sie sich denn konstant mit 10 Pixel pro Frame? Wieso bewegt sie sich nicht konstant mit v * t Pixel pro Frame, wobei v die geschwindigkeit ( z.B. 10 px/s) und t die Zeit des letzten Frames ist?
Dann kannst du auch das Level richtig anpassen, und erhöhst die Geschwindigkeit mit jedem Level. Ich sehe noch immer nicht, was das problem ist.
dani93 hat geschrieben:Je höher das Level, desto kürzer die Zeit zwischen den Frames,
Was hat die Framerate mit dem Level zu tun?? Die Framerate ist eine Technische Entscheidung, die vom Programmierer zu treffen ist. Die hat nichts mit dem Level zu tun, welches eine Spielvariable ist...

Wahrscheinlich war Kerlis pseudocode einwandfrei, deswegen werde ich ihn nicht wiederholen. Was ich aber wiederholen werde ist eine kleine Lehrstunde in Physik.

Die ganze Diskussion dreht sich hier um die Geschwindigkeit, und zwar um die Geschwindigkeit mit der dem User die Bewegung erscheint.
Diese Geschwindigkeit v wird als "Momentangeschwindigkeit" bezeichnet, und ist der Differenzenquotient des Weges s nach der Zeit t:
v = ds / dt

Momentangeschwindkeiten gibt es auf dem PC nicht. Eine Zahl kann in einem Computer kann nicht "gegen 0 gehen".
Was auf dem Computer allerdings ist folgendes, und zwar dass du die Unterschiede zwischen zwei Zuständen bezeichnest. Das würde so aussehen:
v = (s2 - s1) / (t2 - t1)

Hier wäre s2 der Zurückgelegte weg zum Zeitpunkt t2 und s1 der Zurückgelegte weg zum Zeitpunkt t1.
Also was brauchen wir um dem Benutzer eine kontinuirliche Bewegung vorzugaukeln? Zum Zeitpunkt t1 ist die schlange auf Position s1, und zum Zeitpunkt t2 ist die Schlange auf Position t2. So einfach ist das.

Bitte bemerke, dass ich bis jetzt noch kein Wort über Einheiten und Dimensionen verloren habe. v kann in m/s, km/h, oder px/ms angegeben sein, und dementsprechend auch s und t.
Auch noch kein Wort verloren habe ich über eine Implementierung.

Bis dahin muss dir das mal klar werden!

Wenn du soweit bist, dann können wir einen Blick auf die Anwendung wagen.
Wir haben gesagt, dass die gleichung
v = (s2 - s1) / (t2 - t1)
gelten muss, damit eine Bewegung kontinuirlich erscheint.
Jetzt denken wir mal nach, welche variablen der gleichung gegeben und welche gefragt sind. Wie stehts mit v? v ist die Geschwindigkeit, und sollte konstant bleiben (außer bei Levelsprüngen, aber dazu kommen wir später). Wie stets mit (t2 - t1) ? (t2 - t1) ist deine Framezeit! Das ist die Zeit, die der letzte Frame (als beste näherung für das was der jetzige Frame) an Zeit gebraucht hat. Was bleibt übrig? (s2 - s1), na klar! Das ist der Versatz, um den du die Schlange verschieben musst, damit die Bewegung flüssig erscheint.
also lösen wir nach (s2 - s1) auf:
v = (s2 - s1) / (t2 - t1) | * (t2 - t1)
v * (t2 - t1) = (s2 - s1)
(s2 - s1) = v * (t2 - t1)

So, was siehst du hier? Eine schon bekannt gleichung. Demnach ist die Strecke um die du die Schlange versetzen musst (das ist (s2 - s1)) gleich der gewünschten geschwindigkeit (v) mal der Zeit die der Letzte Frame gebrauch hat ( das ist (t2 - t1)).

Also, du misst wie lange ein Frame braucht, und bekommst dadurch (t2 - t1). Du gibst die gewünschte geschwindigkeit FIX an (kann ruhig const sein), denn so schnell wird sich deine Schlange bewegen.
Jetzt multiplizierst du die beiden, und kriegst deinen versatz raus: (t2 - t1)

Das ist eine einfache und doch funktionierende methode um die geschwindigkeit konstant zu halten.

So, nun wolltest du noch, dass die Schlange sich in einem höheren level schneller bewegt?
Sich schneller bewegen heißt, eine höhere Geschwindigkeit haben.
Sagen wir, dass sich die Schlange pro Level um 10 % schneller bewegt. Das würde so aussehen:
v2 = v1 * 110 % = v1 * 1,1

Um die geschwindigkeit zu erhöhen brauchst du nur das v anpassen, und nicht an der Framezeit spielen.

Nochmal: die Framezeit solltest du nach obenhin deckeln, sodass nicht die ganze CPU verbraucht wird. Dass die Framerate nicht immer auf Maximalniveau bleiben kann ist klar, kann gut passieren dass die mal absackt. Nur da passiert nichts, da du deine Bewegung mit den oberen berechnungen ja angepasst hast. Du hast es selbst schon sehr schön formuliert:
dani93 hat geschrieben:großer Weg * wenige FPS ~ kleiner Weg * viele FPS
So ist es, und nicht anders.
Haters gonna hate, potatoes gonna potate.

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: EatTheBlocks

Beitrag von nufan » Fr Feb 13, 2009 9:59 pm

Ok, ich glaub ich habs jetzt verstanden. :)
Das physische mit den Formeln ist mir nicht neu, nur irgendwie hatte ich Probleme damit es im Programm anzuwenden. Ab sofort in Physik besser aufpassen ;) (obwohl ich bezweifle, dass ich je das Huygenssches Prinzip oder Interferenzen in einem Programm verwenden werde...).

Mein letztes Problem ist wie du es nennst das "geringste".
fat-lobyte hat geschrieben:Das zurückrechnen ins "Gitter" ist dein geringstes Problem, das kannst du immer noch jedes mal dort machen wenn der Wert gebraucht wird, z.B. in der Move und Render Funktion. Das ist eine einfache Operation: %. Oder Wenn du deine Pixel in einem int speicherst brauchst du überhaupt keine Operation, sondern nur "position_discr = position_cont;", und der compiler erledigt dein Gitter für dich.
Ich habe jetzt auf dem alten Code aufgebaut (den mit den flüssigen Bewegungen), also sind alle Koordinaten floats. Ich will auf 50 FPS kommen, also ist die maximale Zeit für einen Frame:

Code: Alles auswählen

#define MAXFRAMETIME 1000 / 50
1000 weil SDL_GetTicks Zeit in ms zurückgibt. Die Schleife ist vom FPS-Prinzip her die gleiche wie die von Kerli. Aber wie bekomme ich die Blöcke ins Gitter?

% ergibt doch den Rest. Wenn ich den Rest von der Zahl abziehe sollte eigentlich eine durch 10 teilbare Zahl herauskommen.

Code: Alles auswählen

    dest.x = snake -> x - ((int) snake -> x % 10);
    dest.y = snake -> y - ((int) snake -> y % 10);
Doch in den Kurven fallen dann immer Blöcke aus der Reihe...

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: EatTheBlocks

Beitrag von Kerli » Sa Feb 14, 2009 12:54 am

dani93 hat geschrieben:Ich will auf 50 FPS kommen, also ist die maximale Zeit für einen Frame:
Wohl eher die minimale Zeit. Du kannst verhindern, dass der Computer zu schnell wird, nicht aber das er zu langsam wird :P
dani93 hat geschrieben:% ergibt doch den Rest. Wenn ich den Rest von der Zahl abziehe sollte eigentlich eine durch 10 teilbare Zahl herauskommen.
Ja aber durch kleine Ungenauigkeiten bei der Berechnung kann es zu Ungenauigkeiten kommen, die durch die Rasterung stark auffallen. Deshalb solltest du bei der Bewegung darauf achten, dass die Blöcke nur auf einer "Rasterkreuzung" die Richtung ändern dürfen. Da man das sehr schwer genau erwischen kannst, solltest du die Schlange einfach an der nächst möglichen "Kreuzung" abbiegen lassen. Da musst du dann eventuell einen Teil der Bewegung in eine andere Richtung fortsetzen. Wie ich mir das vorstelle habe ich eh in diesem Thread schon anhand eines Bildes demonstriert. Für die Optik könnte es deshalb auch besser sein Kreise statt Blöcken zu verwenden.

Mit Blöcken müsstest du dir nämlich was anderes überlegen um die Kurven schön zu machen. Möglich wäre es zum Beispiel eine doppelt verkettete Liste mit den Punkten zu führen an denen die Schlange die Richtung gewechselt hat. Der vorderste Punkt bewegt sich dann immer weiter bis die Schlange die Richtung ändert. Dann bleibt der Punkt stehen und vorne wird ein neuer Punkt an die Liste angefügt.

So ähnlich musst du das dann auch mit dem letzten Punkt machen der bewegt sich so lange bis er auf den nächsten Punkt trifft und wird dann einfach gelöscht. Dannach übernimmt der jetzt neue letzte Punkt seine Rolle.

Beim Rendern musst du dann nur mehr zwischen den Punkten die für die Schlange passenden Rechtecke zeichnen. Wenn die Schlange länger werden soll, dann muss der letzte Punkt einfach nur eine gewisse Zeit warten.
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: EatTheBlocks

Beitrag von nufan » Sa Feb 14, 2009 1:22 am

Kerli hat geschrieben:
dani93 hat geschrieben:Ich will auf 50 FPS kommen, also ist die maximale Zeit für einen Frame:
Wohl eher die minimale Zeit. Du kannst verhindern, dass der Computer zu schnell wird, nicht aber das er zu langsam wird :P
Mein ich doch ^^
Kerli hat geschrieben:
dani93 hat geschrieben:% ergibt doch den Rest. Wenn ich den Rest von der Zahl abziehe sollte eigentlich eine durch 10 teilbare Zahl herauskommen.
Ja aber durch kleine Ungenauigkeiten bei der Berechnung kann es zu Ungenauigkeiten kommen, die durch die Rasterung stark auffallen. Deshalb solltest du bei der Bewegung darauf achten, dass die Blöcke nur auf einer "Rasterkreuzung" die Richtung ändern dürfen. Da man das sehr schwer genau erwischen kannst, solltest du die Schlange einfach an der nächst möglichen "Kreuzung" abbiegen lassen. Da musst du dann eventuell einen Teil der Bewegung in eine andere Richtung fortsetzen. Wie ich mir das vorstelle habe ich eh in diesem Thread schon anhand eines Bildes demonstriert. Für die Optik könnte es deshalb auch besser sein Kreise statt Blöcken zu verwenden.
Hört sich ein wenig kompliziert an...
Eigentlich würde ich da lieber beim Klassiker mit den Blöcken bleiben. Aber wenns damit wirklich nicht gut aussieht gehn Kreise auch. Werde mir dann mal SDL_gfx ansehen.
Kerli hat geschrieben:Mit Blöcken müsstest du dir nämlich was anderes überlegen um die Kurven schön zu machen. Möglich wäre es zum Beispiel eine doppelt verkettete Liste mit den Punkten zu führen an denen die Schlange die Richtung gewechselt hat. Der vorderste Punkt bewegt sich dann immer weiter bis die Schlange die Richtung ändert. Dann bleibt der Punkt stehen und vorne wird ein neuer Punkt an die Liste angefügt.

So ähnlich musst du das dann auch mit dem letzten Punkt machen der bewegt sich so lange bis er auf den nächsten Punkt trifft und wird dann einfach gelöscht. Dannach übernimmt der jetzt neue letzte Punkt seine Rolle.
Das find ich schon besser :)
Werde dann mal versuchen das so hinzubekommen.
Kerli hat geschrieben:Beim Rendern musst du dann nur mehr zwischen den Punkten die für die Schlange passenden Rechtecke zeichnen. Wenn die Schlange länger werden soll, dann muss der letzte Punkt einfach nur eine gewisse Zeit warten.
Den Effekt hab ich jetzt auch (nur rein optisch gesehen). Ein neuer Block bekommt bei mir immer die Position des letzten Blocks. Durch das weitersetzen der Position sieht es dann so aus, als würde die Schlange wachsen.


Ok, danke für die ganzen Infos und Hinweise. Ich werde mal zusehen, dass ich mal wieder was alleine hinbekomm :)

Antworten