SoloCodigo

Programación General => C/C++ => Mensaje iniciado por: Germanplz en Sábado 5 de Julio de 2014, 02:33

Título: Ventana que parpadea
Publicado por: Germanplz en Sábado 5 de Julio de 2014, 02:33
Estoy tratando de hacer el juego snake pero tengo un problema para hacer los bordes por alguna razón que desconozco los bordes parpadean y el snake con su comida igual, alguien me podría decir como corregirlo
Código: [Seleccionar]
#include <list>
#include <curses.h>
#include <stdlib.h>
#include <time.h>

class snake {
 private:
    int x, y;
 public:
  snake(  int a,  int b) {
   x = a;
   y = b;
  }
  int getX() { return x; }
  int getY() { return y; }
};

int main() {
 // inicio
 srand ( time(NULL) );
 initscr();
 WINDOW *win = newwin(22,40,0,0);
 start_color();
 start_color();//da color
 noecho();
 curs_set(0);
 keypad(stdscr, TRUE);
 timeout(100);

 std::list<snake> snakes;
 std::list<snake>::iterator it;
 bool salir = false;
 int puntos = 0;
 int dir = 2;
 int comida_x = rand() % 40 + 1;
 int comida_y = rand() % 20 + 1;
 int ch;
 for(int i = 0; i < 2; i++) // puntos de partida de snake
  snakes.push_front(snake(3+i,3));

 while(!salir) {
     // entrada
     ch = getch();
     switch(ch) {
      case KEY_UP:
       dir = 1;
       break;
      case KEY_RIGHT:
       dir = 2;
       break;
      case KEY_DOWN:
       dir = 3;
       break;
      case KEY_LEFT:
       dir = 4;
       break;
      case 'p':
       salir = true;
       break;
     }
     // como se mueve
     snake logica = snakes.front();
     int x = logica.getX();
     int y = logica.getY();
     box(win, '_', '/');
     if(dir == 1){
        y=y-1; // hacia arriba
      }
     else if(dir == 2){
        x=x+1; // hacia la derecha
      }
     else if(dir == 3){
        y=y+1; // hacia abajo:
      }
     else if(dir == 4){
     x=x-1; // hacia izquierda
}
    box(win, '_', '/');
    touchwin(win);
    wrefresh(win);
     snakes.push_front(snake(x, y));

     if(x == comida_x && y == comida_y) {
      comida_x = rand() % 40;
      comida_y = rand() % 20;
   puntos++;
     } else
      snakes.pop_back();

     if(y > 20 || x > 40 || y < 0 || x < 0) // colision con los bordes
      salir = true;
     // salida
     erase();
     init_pair(7,COLOR_WHITE,COLOR_WHITE);
        attron(COLOR_PAIR(7));//aplica color
        attron(COLOR_PAIR(7));
     mvaddch(comida_y,comida_x,'ñ');
     attroff(COLOR_PAIR(7));
    attroff(COLOR_PAIR(7));//deja de aplicar color
     for(it = snakes.begin(); it != snakes.end(); it++) {
      init_pair(1,COLOR_GREEN,COLOR_RED);
        attron(COLOR_PAIR(1));
        attron(COLOR_PAIR(1));//aplica color
      mvaddch((*it).getY(),(*it).getX(),'o');
      attroff(COLOR_PAIR(1));
        attroff(COLOR_PAIR(1));//deja de aplicar color
      if((*it).getY() == y && (*it).getX() == x && it != snakes.begin()) // colision con los bordes
       salir = true;
     }
     mvprintw(0, 5, "Tu puntaje es %i. 'p' para salir.\n", puntos);
     refresh();
    }
    timeout(-1);
    erase();
    mvprintw(0, 5, "Perdiste, sacaste un total de %i puntos.\n", puntos);
    refresh();
    getch(); // esperar la salida(perder o que se retire)

 endwin();
 return 0;
}
Título: Re:Ventana que parpadea
Publicado por: m0skit0 en Domingo 6 de Julio de 2014, 18:31
Lo siento, no puedo entener tu código formateado así. Si lo formateas de una manera legible podría echarle un vistazo (yo hice en su día el típico snake de consola en C).
Título: Re:Ventana que parpadea
Publicado por: g_cr en Jueves 10 de Julio de 2014, 20:40
Germanplz El problema surge en que estas usando una secuencia clear y borrando la pantalla para redibujarla nuevamante. eso provoca el parpadeo.
Para solucionar esto te aconsejo que investigues el tema de paginacion para la pantalla grafica. no tengo ningun ejemplo a mano en este momento y hace bastante que no lo hago.

la idea es la siguiente:
dibujas la pantalla en una memoria de video no visible y luego conmutas la pagina actual por la que tenes en memoria. y usas la memoria de video de la primer pantalla para el siguiente cuadro.
 de esta forma no vas a ver el parpadeo que se produce al redibujar, ya que el barrido de pantalla encuentra lugares sin valor (negro)

te repito no tengo aca el codigo, pero solo tenes que agregarle un par de instrucciones a lo que tenes hecho.

Suerte