[C con Clase] Juego de la serpiente

Programante programante en gmail.com
Mar Oct 9 22:53:58 CEST 2007


Alejandro escribió:
> Hola lista:
>
> Estoy intentando hacer una especie de juego de la serpiente para MS-DOS. Mi problema es que hasta ahora temgo creada la parte que reconoce las teclas y mueve la serpiente. Para probarlo creé un minimapa y puse un rombo como serpiente, y con las teclas mueves al rombo. O esa era mi intención porque lo que quiero es que ese rombo se borre cada vez que el usuario teclee una flecha y se reescriba en la nueva casilla. Este es el codigo hasta ahora:
>
> #include <iostream>//Librería para cout, cin...
> #include <cstdio>//Librería para el archivo de texto
> #include <ctime>//Librería con las funciones del tiempo
> #include <cstring>//Librería con tratamientos para cadenas
> #include <conio.h>//Conio para mover la serpiente
>
> #define  LEFT     0x4b //izquierda 
> #define  RIGHT    0x4d //derecha 
> #define  UP       0x48 //arriba 
> #define  DOWN     0x50 //abajo 
> #define  ENTER    0x0d //enter
>
> #define TAM_LADO 20
> #define TAM_ALTO 10//Dimensiones del mapa
>
> using namespace std;
>
> class Animal
> {
>       public:
>              void MueveAnimal(int, int);//Función para mover el animal
>              int CoorX(){return x;};
>              int CoorY(){return y;};//Devuelven las coordenadas actuales
>              Animal(int InX = TAM_ALTO / 2, int InY = TAM_LADO / 2);//Constructor
>              
>       private:
>               int x;
>               int y;//Variables con la posicion inicial
> }Serpiente;//Clase para crear la serpiente
>
> void Animal::MueveAnimal(int Nx, int Ny)//Función para mover la serpiente
> {
>      x = Nx;
>      y = Ny;//Cambia las coordendas
> }
>
> Animal::Animal(int InX, int InY)//Constructor
> {
>                    x = InX;
>                    y = InY;//Inicializa las variables
> }
>
>   
Estás usando una clase, pero el diseño que utilizas no es basado en clases.
Considera la posibilidad de quitar la clase.

> int main()//Función principal
> {
>     char tecla;//Captura la tecla pulsada
>     bool Salir = false;
>     int CopX;
>     int CopY;//Copia de las coordenadas actuales
>     int x = 5;
>     int y = 10;//Inicio del jugador
>     int mapa[TAM_ALTO][TAM_LADO] = {
>                                          1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
>                                          1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
>                                          1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
>                                          1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
>                                          1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
>                                          1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
>                                          1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
>                                          1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
>                                          1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
>                                          1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};//Mapa del juego
>     
>     
>     mapa[x][y] = 2;//Posición inical del jugador
>     
>     
>     for(int k = 0; k < TAM_ALTO; k++)
>     {
>             for(int y = 0; y < TAM_LADO; y++)
>             {
>                     if(mapa[k][y] == 0)cout << (char)32;
>                     if(mapa[k][y] == 1)cout << (char)2;
>                     if(mapa[k][y] == 2)cout << (char)4;
>             }
>             cout << endl;
>     }//Inicialización del mapa
>   
Aquí dibujamos el mapa por primera vez.
Te falta hacer un cls al inicio (prueba a abrirlo en una consola que ya 
tenga texto).

>     while(tecla != ENTER)//Game loop central
>     {
>                 CopX = x;
>                 CopY = y;//Hace copias de las coordenadas
>                 
>                 do
>                 {
>                          tecla = getch();
>                          
>                          switch(tecla)
>                          {
>                                       case UP:
>                                            Serpiente.MueveAnimal((x--), y);
>                                            Salir = true;
>                                            break;
>                                            
>                                       case DOWN:
>                                            Serpiente.MueveAnimal((x++), y);
>                                            Salir = true;
>                                            break;
>                                            
>                                       case LEFT:
>                                            Serpiente.MueveAnimal(x, (y--));
>                                            Salir = true;
>                                            break;
>                                       
>                                       case RIGHT:
>                                            Serpiente.MueveAnimal(x, (y++));
>                                            Salir = true;
>                                            break;
>                                            
>                                       default:
>                                               break;
>                          }
>                 }while(!Salir);
>                          
>                          mapa[Serpiente.CoorX()][Serpiente.CoorY()] = 2;//Cambia de posicion la serp.
>                          mapa[CopX][CopY] = 0;//Deja libre el anterior hueco                         
>   
El problema es que no estás dejando libre el hueco anterior, sino el 
actual. CopX es igual a Serpiente.CoorX()  y CopY a Serpiente.CoorY()
Al usar el postincremento y el postdecremento en las líneas anteriores, 
pasas a MueveAnimal el valor de x/y  y *luego* cambias el valor de x o de y.

Cambiando el código por:

                                      case UP:
                                           Serpiente.MueveAnimal(--x, y);
                                           Salir = true;
                                           break;
                                           
                                      case DOWN:
                                           Serpiente.MueveAnimal(++x, y);
                                           Salir = true;
                                           break;
                                           
                                      case LEFT:
                                           Serpiente.MueveAnimal(x, --y);
                                           Salir = true;
                                           break;
                                      
                                      case RIGHT:
                                           Serpiente.MueveAnimal(x, ++y);
                                           Salir = true;
                                           break;

ya tenemos un programa donde movemos un rombo por la pantalla (incluidos 
los bordes).

Si además quitamos la línea  mapa[CopX][CopY] = 0;  el rombo "deja 
estela", que es la característica básica del juego de la serpiente.

>                          system("cls");//Limpia la pantalla
>                          
>                          for(int k = 0; k < TAM_ALTO; k++)
>                          {
>                                  for(int y = 0; y < TAM_LADO; y++)
>                                  {
>                                          if(mapa[k][y] == 0)cout << (char)32;
>                                          if(mapa[k][y] == 1)cout << (char)2;
>                                          if(mapa[k][y] == 2)cout << (char)4;
>                                  }
>                                  cout << endl;
>                          }//Dibuja el nuevo mapa
>   
Y aquí dibujamos el mapa de nuevo. Deberías mover el código a una 
función específica.

>     }
>                                            
>                                            
>     
>     cin.get();//Mantiene abierto el programa
>     return 0;
> }
>
> ¿Cual es el fallo? No comprendo por qué la pantalla va con retraso de lo que yu hago...:-(  Gracias por vuestra atención y un saludo





Más información sobre la lista de distribución Cconclase