EatTheBlocks

Präsentation und Organisation von eigenen Projekten
nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: EatTheBlocks

Beitrag von nufan » Di Jan 06, 2009 1:05 am

fat-lobyte hat geschrieben: Na du Held? Gratuliere, du hast Fuss' System zerstört! bist du jetzt zufrieden? ;-)
Fuss, kannst dich schon mal bei dani bedanken.
Sorry :oops:
Wie schon im verlinkten Beitrag erwähnt habe ich alle Pakete getestet und bei mir funzt noch immer alles.
Aber war das jetzt überhaupt dieser Rechner oder der andere?
fat-lobyte hat geschrieben:(Echt jetzt! Man lernt selten so schnell so viel über sein System, wenn man nicht gerade versucht etwas zu reparieren, was man selbst zerstört hat! :-) )
Dem kann ich nur zustimmen. ;)
Gerade wieder .dmrc Berechtigungen gefixt, obwohl ich da nichts dran geändert habe...

/* edit by Kerli: Ich hab die Diskussion zu den Paketen und Backups einmal abgeschnitten, da sie nicht mehr wirklich zum Projekt von dani passen. Hier gehts zur Diskussion. */

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

Re: EatTheBlocks

Beitrag von nufan » Di Jan 13, 2009 3:47 pm

Heute hab ich da mal wieder weitergearbeitet.
*klick*

Kompilieren einfach mit "make". Starten kann man auch mit "make run" (Standardeinstellungen, 800*600, Fenstermodus).

Zum kompilieren wird "ibsdl-ttf2.0-dev" und ggf. auch "libsdl-ttf2.0-0" benötigt (natürlich über die Paketverwaltung ;) ).

Die Änderung sind in "CHANGELOG" ersichtlich.

Ich hoffe, dass das mit dem neuen Webspace klappt, kann es leider nicht testen.

Und könnte bitte ein Moderator hier einen Hinweis setzen die Pakete nicht zu installieren?

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

Re: EatTheBlocks

Beitrag von Kerli » Di Jan 13, 2009 4:03 pm

dani93 hat geschrieben:Heute hab ich da mal wieder weitergearbeitet.
Ich hab jetzt keine Zeit gehabt mir den Code etwas anzuschauen, aber du hast irgendein Problem mit der Bewegung, weil bei mir Bewegt sich die Schlange nur nach oben und nach links und sie wirkt auch recht kurz...
dani93 hat geschrieben:Zum kompilieren wird "ibsdl-ttf2.0-dev" und ggf. auch "libsdl-ttf2.0-0" benötigt (natürlich über die Paketverwaltung ;) ).
Man braucht nur "ibsdl-ttf2.0-dev" installieren. Das ist sowieso von "libsdl-ttf2.0-0" abhängig.
dani93 hat geschrieben:Und könnte bitte ein Moderator hier einen Hinweis setzen die Pakete nicht zu installieren?
Zufrieden? ;)
"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 » Di Jan 13, 2009 4:23 pm

Kerli hat geschrieben:du hast irgendein Problem mit der Bewegung, weil bei mir Bewegt sich die Schlange nur nach oben und nach links
Wie? Wo? Bei mir gehen alle vier Richtungen.
Kerli hat geschrieben:sie wirkt auch recht kurz...
Wenn man ein bisschen länger spielt, wird sie noch lang :)
Aber ich denke da stimmt was zwischen der Dauer der Frames und der Bewegung nicht.
Aber zurzeit ist die Länge der Schlange auch nur zur Zierde da, weil man noch sich selbst "fressen" kann.
Kerli hat geschrieben:Zufrieden? ;)
Hmmm... bis auf das, dass der Kommentar falsch gesetzt ist (/*) ists ganz OK :D

EDIT:
Ich bin die Sache jetzt mal ganz anders angegangen...
Ich mache jetzt am Ende jedes Frames

Code: Alles auswählen

SDL_Delay ((int) (level / speed * 200));
Wobei "level" nach jedem gefressenen Block erhöht wird und "speed" die Dauer eines Frames ist. Bei mir funktioniert es jetzt ganz gut.
*klick*

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

Re: EatTheBlocks

Beitrag von Kerli » Di Jan 13, 2009 5:29 pm

dani93 hat geschrieben:
Kerli hat geschrieben:du hast irgendein Problem mit der Bewegung, weil bei mir Bewegt sich die Schlange nur nach oben und nach links
Wie? Wo? Bei mir gehen alle vier Richtungen.
Nach rechts und oben bewegt er sich nur seeeeeeehr langsam (~0.5 Pixel/Sekunde :) )
dani93 hat geschrieben: Hmmm... bis auf das, dass der Kommentar falsch gesetzt ist (/*) ists ganz OK :D
Besser? :P
dani93 hat geschrieben: EDIT:
Ich bin die Sache jetzt mal ganz anders angegangen...
Ich mache jetzt am Ende jedes Frames

Code: Alles auswählen

SDL_Delay ((int) (level / speed * 200));
Wobei "level" nach jedem gefressenen Block erhöht wird und "speed" die Dauer eines Frames ist. Bei mir funktioniert es jetzt ganz gut.
*klick*
Das Problem an diesem Ansatz ist wieder, dass das Spiel auf einem langsameren Computer auch wieder langsamer ist, da du die Geschwindigkeit nicht in Abbhängigkeit der benötigten Zeit hast.

Besser wäre es wenn du so wie vorher die Zeit misst, aber die Koordinaten auf zb float umstellst, da so die Bewegungen genauer erfolgen und nicht gerundet werden. Sonst könnten vor allem auf schnelleren Computern (das könnte auch eine Erklärung für das obere Problem sein - Mein Computer ist recht schnell...) Bewegungen unter einem halben Pixel verschluckt werden.
"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 » Di Jan 13, 2009 6:13 pm

Kerli hat geschrieben:Besser? :P
Bin zufrieden :)
Kerli hat geschrieben:Das Problem an diesem Ansatz ist wieder, dass das Spiel auf einem langsameren Computer auch wieder langsamer ist, da du die Geschwindigkeit nicht in Abbhängigkeit der benötigten Zeit hast.
Das versteh ich nicht ganz...
Ich erklär mal wie ich meinen Ansatz sehe:
Also "level" beginnt bei 1.0 und wird ständig erhöht.
Großer "level" --> kleines Ergebnis bei der Division --> kürzere Pause zwischen den Frames --> Schlange bewegt sich schneller.
Dividiert wird durch die Dauer eines Frames.
Schneller Computer --> kleiner "speed" --> großes Ergebnis bei der Division --> längere Pause bis zum nächsten Frame .
Langsamer Computer --> großer "speed" --> kleines Ergebnis bei der Division --> kurze Pause bis zum nächsten Frame.
Und * 200 um auf ein der Größe her passendes Ergebnis zu kommen.

Seh ich da was falsch?
Mir fällt im Moment keine bessere Lösung ein...
Kerli hat geschrieben:Besser wäre es wenn du so wie vorher die Zeit misst, aber die Koordinaten auf zb float umstellst, da so die Bewegungen genauer erfolgen und nicht gerundet werden.
Kann man Bruchteile von Pixeln zeichnen/berechnen?

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3123
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: EatTheBlocks

Beitrag von cloidnerux » Di Jan 13, 2009 7:08 pm

Du musst dir eine möglichkeit einbauen die Frames pro sekunde zu errechen.
Einfachster ansatz wäre jeden frame ein INT zu erhöhen und jede sekunde zu teilen.
Jezt speicherst du ein ein float time = 1/fps;
Auf einer langsamen maschine wird jezt ein höherer Wert erzeugt als auf einem Schnellen => Gleiche geschwindigkeit
jezt musst du nur jede Bewegung mit diesem Wert multiplizieren.
Und funktione zur ständigen Ermittlung.
Redundanz macht wiederholen unnötig.
quod erat expectandum

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

Re: EatTheBlocks

Beitrag von nufan » Di Jan 13, 2009 10:17 pm

Ich hab mal versucht das ungefähr so zu realisieren...

Code: Alles auswählen

#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>


#define VERSION 0.1
#define SUBVERSION 'b'

#define MAXLENGTH 100

#define UP 0
#define RIGHT 1
#define DOWN 2
#define LEFT 3


typedef struct 
{
  int direction;
  float x, y;
} block_info;

typedef struct
{
  int eaten;
  float x, y;
} fruit_struct;


static block_info snake[MAXLENGTH];
static SDL_Surface *screen;
static fruit_struct fruit;
static int length = 0;
static float level = 1.0;
static long double speed = 0.0;


void parameters (int *w, int *h, int *fullscreen, int argc, char *argv[]);
void draw_snake (int direction[], float newx[], float newy[]);
void draw_fruit ();
void new_fruit ();
void check_input (SDL_Event event, int *run, int *start);
int check_border_score (int *run, int *numeaten, int *score);
void move_snake (int direction[], float newx[], float newy[]);
void display_help ();  
void pause (int *start);
void create_blocks (int nr, int pos);
void draw_end (int score);



int main (int argc, char *argv[])
{

  SDL_Event event;
  Uint16 black;
  int run = 1, w = 800, h = 600, fullscreen = 0, direction[MAXLENGTH], 
      start, startdiff, diff, numeaten = 0, score = 0;
  unsigned int frames = 0;    
  float newx[MAXLENGTH], newy[MAXLENGTH];
  long double fps;

  
  srand (time (NULL));
  
  
  if (argc > 1)
    parameters (&w, &h, &fullscreen, argc, argv);
  
  
  if (SDL_Init (SDL_INIT_VIDEO) != 0)
  {
  
    printf ("Unable to initialize SDL: %s\n", SDL_GetError());
    
    return 1;
  
  }
  
  atexit (SDL_Quit);
  
  
  if(TTF_Init () != 0)
  {
    
    printf("Unable to initialize TTF: %s\n", TTF_GetError ());
    
    return 1;
 
  }    
  
  
  if (fullscreen)
    screen = SDL_SetVideoMode (w, h, 16, SDL_FULLSCREEN);
    
    else
      screen = SDL_SetVideoMode (w, h, 16, SDL_DOUBLEBUF);
  
  
  if (screen == NULL)
  {
  
    printf ("Unable to set video mode: %s\n", SDL_GetError());
    
    return 1;
  
  }


  black = SDL_MapRGB (screen -> format, 0, 0, 0);
  
  snake[0].x = (float) (screen -> w / 2) - 10.0;
  snake[0].y = (float) (screen -> h / 2) - 10.0;
  snake[0].direction = LEFT;
  
  create_blocks (5, 1);
  
  fruit.eaten = 0;
  new_fruit ();
  
  SDL_Delay (500);
  
  startdiff = SDL_GetTicks ();
  
  
  while (run)
  {    
  
    start = SDL_GetTicks ();   
  
    frames++;
        
   
    while (SDL_PollEvent (&event))
    {   
  
      switch (event.type)
      {
       
        case SDL_KEYDOWN: check_input (event, &run, &start);
                          break;                       
       
        case SDL_QUIT: run = 0;
                       break;                  
                       
      }   
  
    } 
    
    
    SDL_FillRect (screen, NULL, black);       
         
    draw_snake (direction, newx, newy);   
    draw_fruit ();   

    check_border_score (&run, &numeaten, &score);
    
    move_snake (direction, newx, newy);
    
    diff = ((start - startdiff));    
    
    fps = (long double) frames / diff * 2;
    
    speed = 1.0 / fps / level;
    
    SDL_Delay (speed);
     
  }  

  return 0;

}



void parameters (int *w, int *h, int *fullscreen, int argc, char *argv[])
{

  int i;
  
  for (i = 1; i < argc; i++)
  {
  
    if (strcmp (argv[i], "-w") == 0)
    {
    
      if (atoi (argv[i + 1]) >= 256)
        *w = atoi (argv[i + 1]);
        
        else
        {
        
          printf ("Window too small.\n");
          
          exit (0);
        
        }
      
    } 
      
    else if (strcmp (argv[i], "-h") == 0)
    {
      
      if (atoi (argv[i + 1]) >= 256)
        *h = atoi (argv[i + 1]);
        
        else
        {
        
          printf ("Window too small.\n");
          
          exit (0);
        
        }        
    
    } 
      
    else if (strcmp (argv[i], "--help") == 0)
    {
      display_help ();  
      exit (0);
    }
    
    else if (strcmp (argv[i], "--full") == 0)
      *fullscreen = 1;
  
  }

}



void display_help ()
{

  printf ("\nEatTheBlocks V%.1f%c\n", VERSION, SUBVERSION);
  
  printf ("\nOptions:\n\t-w\t=\tspecify windows width\n");
  printf ("\t-h\t=\tspecify window hight\n\t--full\t");
  printf ("=\tstart game in fullscreen mode\n\t--help\t=\tshow this help\n");

}



void draw_snake (int direction[], float newx[], float newy[])
{

  int i;
  SDL_Rect dest;
  Uint16 white;
  
  dest.w = 10;
  dest.h = 10;
  
  for (i = 0; i < length; i++)
  {
    
    dest.x = snake[i].x;
    dest.y = snake[i].y;
    
    white = SDL_MapRGB (screen -> format, 255, 255, 255);
    SDL_FillRect (screen, &dest, white);

    direction[i] = snake[i].direction;
    newx[i] = snake[i].x;
    newy[i] = snake[i].y;
  
  }

}



void draw_fruit ()
{

  SDL_Rect dest;
  Uint16 green;
  
  dest.x = fruit.x;
  dest.y = fruit.y;
  dest.w = 10;
  dest.h = 10;
  
  green = SDL_MapRGB (screen -> format, 0, 255, 0);
  SDL_FillRect (screen, &dest, green);
  
  SDL_Flip (screen);

}



void new_fruit ()
{
  
  fruit.x = (float) ((rand () % (screen -> w - 20)) + 5);
  
  fruit.y = (float) ((rand () % (screen -> h - 20)) + 5);

}



void check_input (SDL_Event event, int *run, int *start)
{

  SDL_keysym key = event.key.keysym;

  if (key.sym == SDLK_UP && snake[0].direction != DOWN)
    snake[0].direction = UP;
    
  else if (key.sym == SDLK_RIGHT && snake[0].direction != LEFT)
    snake[0].direction = RIGHT;
    
  else if (key.sym == SDLK_DOWN && snake[0].direction != UP)
    snake[0].direction = DOWN;
  
  else if (key.sym == SDLK_LEFT && snake[0].direction != RIGHT)
    snake[0].direction = LEFT;      
    
  else if (key.sym == SDLK_p)
    pause (start);      
    
  else if (key.sym == SDLK_ESCAPE)
    *run = 0; 

}



int check_border_score (int *run, int *numeaten, int *score)
{

  if ((snake[0].x < 0) || ((snake[0].x + 10) > screen -> w))
  {
  
    printf ("Game over.\nScore: %d\n", *score);
    
    *run = 0;
    
    draw_end (*score);
    
    return 1;
  
  }
  
    else if ((snake[0].y < 0) || ((snake[0].y + 10) > screen -> h))
    {
    
      printf ("Game over.\nScore: %d\n", *score);

      *run = 0;
    
      draw_end (*score);
    
      return 1;     
    
    }
  
    
  if ((snake[0].x < (fruit.x + 10) && snake[0].x > (fruit.x - 10))) 
  {
  
    if ((snake[0].y < (fruit.y + 10) && snake[0].y > (fruit.y - 10)))
    {
    
      (*score) += (100 * level);
  
      (*numeaten)++;
  
    
      if (length < MAXLENGTH)
        create_blocks (1, length);
  
      new_fruit ();
  
      level += 0.01;
  
    }
  
  } 
    
  return 0;  
    
}



void move_snake (int direction[], float newx[], float newy[])
{

  int i;
  
  
  for (i = 0; i < length; i++)
  {  
    
    if (i == 0)
    {
    
      if (snake[0].direction == UP)
        snake[0].y -= 10.0;
      
      else if (snake[0].direction == RIGHT)
        snake[0].x += 10.0;
      
      else if (snake[0].direction == DOWN)
        snake[0].y += 10.0;
      
      else if (snake[0].direction == LEFT)
        snake[0].x -= 10.0;
    
    }
    
      else
      {
        snake[i].direction = direction[i - 1]; 
        snake[i].x = newx[i - 1];
        snake[i].y = newy[i - 1];
      }
  
  }

}



void pause (int *start)
{

  int pausegame = 1, time1, time2;
  SDL_Event event;
  SDL_keysym key;
  
  time1 = SDL_GetTicks ();
  
 
  while (pausegame)
  {
  
    while (SDL_PollEvent (&event))
    {   
  
      switch (event.type)
      {
       
        case SDL_KEYDOWN: 
                         
                          key = event.key.keysym;
                       
                          if (key.sym == SDLK_p)
                            pausegame = 0;

                          break;                                   
                       
      }   
  
    }   
  
  }
  
  time2 = SDL_GetTicks ();
  
  *start -= (time1 - time2);

}



void create_blocks (int nr, int pos)
{

  int i;
  
  for (i = 0; i < nr; i++, pos++)
  {

    if (snake[pos - 1].direction == UP)
    {
    
      snake[pos].x = snake[pos - 1].x;
   
      snake[pos].y = snake[pos - 1].y + 10.0;
   
    }
    
      else if (snake[pos - 1].direction == DOWN)
      {
      
        snake[pos].x = snake[pos - 1].x;
   
        snake[pos].y = snake[pos - 1].y - 10.0;      
      
      }
      
        else if (snake[pos - 1].direction == RIGHT)
        {
        
          snake[pos].x = snake[pos - 1].x - 10.0;
   
          snake[pos].y = snake[pos - 1].y;
        
        }
        
          else if (snake[pos - 1].direction == LEFT)
          {
          
            snake[pos].x = snake[pos - 1].x + 10.0;
   
            snake[pos].y = snake[pos - 1].y;
          
          }
   
    snake[pos].direction = snake[pos - 1].direction;
  
  }
  
  length = pos;

}



void draw_end (int score)
{

  SDL_Surface *text, *gameover;
  SDL_Rect dest;
  SDL_Color color = {0, 255, 0}, color2 = {255, 0, 0};
  TTF_Font *font, *font2;
  Uint16 rectcolor;
  char charscore[30], buffer[10];
  
  
  strcpy (charscore, "Score: \0");
  sprintf (buffer, "%d", score);
  strcat (charscore, buffer);
  
  dest.x = (screen -> w / 2) - 100;
  dest.y = (screen -> h / 2) - 50;
  dest.w = 210;
  dest.h = 40;
  
  rectcolor = SDL_MapRGB (screen -> format, 0, 0, 0);
  SDL_FillRect (screen, NULL, rectcolor);  
  
  rectcolor = SDL_MapRGB (screen -> format, 255, 255, 255);
  SDL_FillRect (screen, &dest, rectcolor);
  
  font = TTF_OpenFont ("/usr/share/fonts/truetype/msttcorefonts/arial.ttf", 30);
  font2 = TTF_OpenFont ("/usr/share/fonts/truetype/msttcorefonts/arial.ttf", 35);
  
  
  if (font != NULL && font2 != NULL)
  {
     
    text = TTF_RenderText_Solid (font, charscore, color); 
    gameover = TTF_RenderText_Solid (font2, "GAME OVER", color2);   
    
    if (text != NULL && gameover != NULL)
    {

      SDL_BlitSurface (text, NULL, screen, NULL); 
      
      SDL_BlitSurface (gameover, NULL, screen, &dest);

      SDL_Flip (screen);
      
      SDL_Delay (3000);

    }
    
      else
        printf ("Unable to blit text: %s\n", TTF_GetError ());

  }
  
    else
      printf ("Unable to load font: %s\n", TTF_GetError ());

}
Bitte auch auf High-End-PCs testen :)
Mir ist auch aufgefallen, dass die Geschwindigkeit schwankt.
Außerdem ist diese Methode etwas unsicher. Wenn es mehr Frames gibt als unsigned int fast, hab ich ein Problem...
Unsigned int geht zwar bis 4.294.967.295 (also müsste man ziiiiiiiemlich lange spielen ;) ), trotzdem ist das aber eine Unsicherheit.

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

Re: EatTheBlocks

Beitrag von Kerli » Mi Jan 14, 2009 12:29 am

dani93 hat geschrieben:Mir ist auch aufgefallen, dass die Geschwindigkeit schwankt.
Das liegt daran, dass du die Framezeit über die gesamte Laufzeit mittelst. Jetzt überleg dir einmal was passiert wenn das Rendern aus irgendeinem Grund einmal deutlich länger oder kürzer braucht...

Deshalb solltest du es so machen wie ich es dir schon vorher irgendwann gesagt habe. Die Zeit am Anfang misst du eh schon jetzt brauchst du nur mehr die Differenz bilden und kannst daraus deine Speedvariable berechnen. Jetzt musst du aber auch noch die Bewegung von dieser Variablen abhängig machen, damit bei einer höheren Framerate auch eine kleinere Bewegung pro Frame erfolgt. Das könnte dann in etwa so ausschauen:

Code: Alles auswählen

while(run)
{
  start = SDL_GetTicks();

  object.render();

  object.x_ += speed * move.x_;
  object.y_ += speed * move.y_;  

  speed = (SDL_GetTicks() - start) * level * speed_factor; // speed_factor sollte float oder double sein (zb ~0.05)
}
(Ja ich weiß, es gibt keine Klassen in C :D)

So sollte das eigentlich funktionieren. Dann hast du nur mehr ein Problem mit den Teilen der Schlange, die dem ersten Teil folgen sollen, da du aufgrund der nicht mehr gleichen Bewegung in jedem Frame, dem Nachfolgeblock nicht die Koordinaten seines Vorgängers zuweisen kannst.

Dazu ist mir auch gleich ein Lösungsansatz eingefallen, nämlich dass du die Blöcke einfach der Reihe nach von vorne nach hinten bewegst. Das machst du ja jetzt auch schon, nur darfst du den Blöcken nicht mehr die Position des Vorgängers zuweisen, sondern musst sie auch entsprechend der Speedvariable bewegen. Probleme werden dann aber in Kurven auftreten, weshalb ich für eine bessere Optik Kugeln statt Blöcke nehmen würde ;)

Jetzt aber zum eigentlichen Problem. Wenn der Vorgänger eines Schlangenteiles sich in die gleiche Richtung bewegt wie der aktuelle Teil, dann kannst du ihn einfach geradeaus weiterbewegen. Wenn der Vorgänger sich aber in eine andere Richtung bewegt, dann musst den aktuellen Teil der Schlange nur so weit bewegen, bis sich der Teil wieder auf einer waagrechten oder senkrechten Linie mit seinem Vorgänger befindet dh. beide die gleiche x- oder y-Koordinate haben. Dann nimmt dieser Teil die Bewegungsrichtung seines Vorgängers an und bewegt sich noch die übrig gebliebene Wegstrecke für den aktuellen Frame in die neue Richtung. Dabei kann es natürlich auch passieren, dass in einem Frame gar kein Richtungswechsel stattfindet, da die zur Verfügung stehende Bewegungsstrecke zu kurz sein kann um den Punkt an dem die Schlange einen Richtungswechsel gemacht hat zu erreichen.

Hier ist noch eine kleine Skizze dazu:
schlange.png
Besonders der Übergang vom mittleren zum rechten Bild ist interessant, da sich dort die zweite Kugel zuerst hinauf und dann erst nach rechts bewegt hat.

So, jetzt hab ich aber genug geschrieben. Ich hoffe es waren ein paar nützliche Anregungen dabei ;)
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
"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 » Mi Jan 14, 2009 12:06 pm

Kerli hat geschrieben:Jetzt überleg dir einmal was passiert wenn das Rendern aus irgendeinem Grund einmal deutlich länger oder kürzer braucht...
Stimmt... alleine wenn man einen Block frisst dauert das schon länger (wenn auch nur sehr gering).
Kerli hat geschrieben:Deshalb solltest du es so machen wie ich es dir schon vorher irgendwann gesagt habe. Die Zeit am Anfang misst du eh schon jetzt brauchst du nur mehr die Differenz bilden und kannst daraus deine Speedvariable berechnen. Jetzt musst du aber auch noch die Bewegung von dieser Variablen abhängig machen, damit bei einer höheren Framerate auch eine kleinere Bewegung pro Frame erfolgt. Das könnte dann in etwa so ausschauen:

Code: Alles auswählen

    while(run)
    {
      start = SDL_GetTicks();

      object.render();

      object.x_ += speed * move.x_;
      object.y_ += speed * move.y_; 

      speed = (SDL_GetTicks() - start) * level * speed_factor; // speed_factor sollte float oder double sein (zb ~0.05)
    }
Das Problem ist, dass speed auch einen Anfangswert braucht. Den kann ich aber höchstens für mich anpassen. Oder ich setze die Variable am Anfang auf 0 und im 1. Frame bewegt sich nichts.
Kerli hat geschrieben:Das machst du ja jetzt auch schon, nur darfst du den Blöcken nicht mehr die Position des Vorgängers zuweisen, sondern musst sie auch entsprechend der Speedvariable bewegen.
Also weise ich die alte Position des vorhergehenden Blocks zu und Multipliziere zusätzlich noch mit speed.
Kerli hat geschrieben:Probleme werden dann aber in Kurven auftreten, weshalb ich für eine bessere Optik Kugeln statt Blöcke nehmen würde ;)
Was für Probleme? Optik ist zurzeit noch zweitrangig. Es soll mal überhaupt richtig funktionieren :)
Kerli hat geschrieben:So, jetzt hab ich aber genug geschrieben. Ich hoffe es waren ein paar nützliche Anregungen dabei ;)
Ja, vielen Dank :)
Ich werde mir das noch mal alles genau ansehen, weiß aber nicht, wann ich da wieder richtig weitermachen kann.

Antworten