AYUDA! Desaparecen caracteres en mi juego C++

Iniciado por kyzo98, 27 Febrero 2015, 20:15 PM

0 Miembros y 1 Visitante están viendo este tema.

kyzo98

Hola de nuevo amigos

Siento repetirme, pero tengo otro problema jeje...

Esta vez se trata de que como verán en la siguiente imagen, hay partes de los límites del mapa y otros caracteres que desaparecen nada más ejecutar el juego.
Por más que busco el problema no lo encuentro.

Dejo el código y la imágen a ver si me puede ayudar:

https://drive.google.com/file/d/0B8cLslsV-jHaY1dnTThsRm9VQzg/view?usp=sharing

#include<stdio.h>
#include<windows.h>
#include<conio.h>
#include<stdlib.h>
#include<list>
using namespace std;

#define ARRIBA 72
#define IZQUIERDA 75
#define DERECHA 77
#define ABAJO 80


void gotoxy(int x, int y){
    HANDLE hCon;
    hCon = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD dwPos;
    dwPos.X = x;
    dwPos.Y = y;

    SetConsoleCursorPosition(hCon, dwPos);
         
}

void OcultarCursor(){
    HANDLE hCon;
    hCon = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_CURSOR_INFO cci;
    cci.dwSize = 2;
    cci.bVisible = FALSE;
   
    SetConsoleCursorInfo(hCon,&cci);
   
}

void pintar_limites(){
     for(int i = 2 ; i<78 ; i++){
           gotoxy(i,3); printf("%c",205);
           gotoxy(i,33);printf("%c",205);
     }
     for(int i = 4 ; i<33 ; i++){
           gotoxy(2,i); printf("%c",186);
           gotoxy(77,i);printf("%c",186);
     }
     
     gotoxy(2,3);  printf("%c",201);
     gotoxy(2,33); printf("%c",200);
     gotoxy(77,3); printf("%c",187);
     gotoxy(77,33);printf("%c",188);
     
}

class NAVE{
    int x,y;
    int corazones;
    int vidas;
public:
    NAVE(int _x, int _y, int _corazones, int _vidas): x(_x),y(_y),corazones(_corazones), vidas(_vidas){}
    int X(){ return x;}
    int Y(){ return y;}
    void COR() { corazones--; }
    void pintar();
    void borrar();
    void mover(char);
    void pintar_corazones();
    void morir();
};

void NAVE::pintar(){
    gotoxy(x,y);  printf("  %c",30);
    gotoxy(x,y+1);printf(" %c%c%c",40,207,41);
    gotoxy(x,y+2);printf("%c%c %c%c",30,190,190,30);
   
}

void NAVE::borrar(){
     gotoxy(x,y);  printf("     ");
     gotoxy(x,y+1);printf("     ");
     gotoxy(x,y+2);printf("     ");
     
}

void NAVE::mover(char key){
    if(key){
        borrar();
        if(key == 'a' && x > 3) x--;
        if(key == 'd' && x+5 < 77) x++;
        if(key == 'w' && y > 4) y--;
        if(key == 's' && y+3 < 33) y++;
        if(key == 'e')corazones--;
        pintar();
        pintar_corazones();
    }
}

void NAVE::pintar_corazones(){
     
    gotoxy(50,2); printf("Vidas %d",vidas);
    gotoxy(64,2); printf("Salud");
    gotoxy(70,2); printf("     ");
    for(int i = 0 ; i < corazones; i++){
          gotoxy(70+i,2); printf("%c",3);
    }
}

void NAVE::morir(){
    if(corazones == 0){
          borrar();
          gotoxy(x,y);   printf(" *** ");
          gotoxy(x,y+1); printf("*****");
          gotoxy(x,y+2); printf(" *** ");
          Sleep(200);
         
          borrar();
          gotoxy(x,y);   printf(" * * ");
          gotoxy(x,y+1); printf("  *  ");
          gotoxy(x,y+2); printf(" * * ");
          Sleep(200);
          borrar();
         
          vidas--;
          corazones = 3;
          pintar_corazones();
          pintar();
               
    }   
}

class AST{
    int x,y;
public:
    AST(int _x, int _y):x(_x),y(_y){}
    void pintar();
    void mover();
    void choque(NAVE &N);
};

void AST::pintar(){
    gotoxy(x,y); printf("%c",184);     
}

void AST::mover(){
    gotoxy(x,y); printf(" ");
    y++;
    if(y > 32){
        x = rand()%71 + 4;
        y = 4;     
    }
    pintar();
}

void AST::choque(NAVE &N){
    if( x >= N.X() && x < N.X()+5 && y >= N.Y() && y <= N.Y()+2){
         N.COR();
         N.borrar();
         N.pintar();
         N.pintar_corazones();
         x = rand()%71 + 4;
         y = 4;
    }     
}

class BALA{
    int x,y;
public:
    BALA(int _x, int _y):x(_x),y(_y){}
    int X() { return x;}
    int Y() { return y;}
    void mover();
    bool fuera();   
};

void BALA::mover(){
    gotoxy(x,y); printf(" "); 
    y--;
    gotoxy(x,y); printf(".");       
}

bool BALA::fuera(){
    if(y == 4) return true;
    return false;     
}

int main(){
   
    OcultarCursor();
    pintar_limites();
    NAVE N(37,30,3,3);
    N.pintar();
    N.pintar_corazones();
   
    list<AST*> A;
    list<AST*>::iterator itA;
    for(int i=0; i<5; i++){
         A.push_back(new AST(rand()&75 + 3, rand()&5 + 3));
    }
   
    list<BALA*> B;
    list<BALA*>::iterator it;
   
    bool game_over = false;
    while(!game_over){
           
            /*
            Mira el cambio que he hecho aquí:
             - en vez de llamar a getch() aquí y luego dentro de NAVE::mover(), lo hago una vez
               eso es porque getch() procesa la tecla actual y limpia el buffer; en otras palabras, una vez
               que llamas a getch(), C++ ya piensa que no hay ninguna tecla pulsada, y la próxima vez que llames
               a getch() dentro de NAVE::mover, va a creer que no hay tecla pulsada y no funcionará.
               Así que simplemente guardo el valor y lo uso aquí una vez, y abajo, lo paso a NAVE::mover(key)
               como primer y único parámetro / argumento
            */
            char key = 0;
           
            if (kbhit())
                key = getch();
           
            if(key == 'b') 
                B.push_back(new BALA(N.X()+2, N.Y()-1));
           
            for(it = B.begin(); it != B.end(); it++){
                (*it)->mover(); 
                if((*it)->fuera()){
                    gotoxy((*it)->X(),(*it)->Y()); printf(" ");
                    delete(*it);
                    it = B.erase(it);     
                }     
            }
           
            for(itA = A.begin(); itA != A.end(); itA++){
                 (*itA)->mover();
                 (*itA)->choque(N);   
            }
           
            N.morir();
            N.mover(key);
            Sleep(30);
           
    }
    system("pause");
    return 0;
}

vangodp

Si pones un valor que vaya mas lento el juego puedes ver lo que pasa.

Unos cuantos asteroides se pintan encima de la linea, luego como se borra el asteroide para que se vaya bajando se queda en blanco por que las lineas no las estas refrescando, ademas no hay por que refrescarlas, solo hay que refrescar los elementos que se mueven, todo lo demás será trabajo extra.

La solución esta en arreglar las llamadas a rand que creo que las estas haciendo mal. justo en esta linea: A.push_back(new AST(rand()&75 + 3, rand()&5 + 3));

...Tienes el borde de la pantalla que inicia a partir de la 4ª letra y lo mismo pasa con la parte de arriba, inicia en la 4ª linea.   si quieres hacer un rand que te funciones prueba eso:  bordeIzquierdo + rand() % bordeDerecho donde el borde derecho inicie dentro de ese "marco", creo que un 4 seria lo suyo. El borde derecho es lo que hace lo mismo pero impide que se salga por el lado derecho. En otras palabras... 4 + rand() % 75 hace que los asteroides inicien en la coordenada 4 y no pasen de la 74.

Ademas falto poner el srand() para que te genere valores aleatorios. te dejo el código como lo arregle y me funciono perfecto.

Quede claro que no mire nada más ;)

http://codepad.org/yNUTWY4K

kyzo98

Cita de: vangodp en 28 Febrero 2015, 10:57 AM
Si pones un valor que vaya mas lento el juego puedes ver lo que pasa.

Unos cuantos asteroides se pintan encima de la linea, luego como se borra el asteroide para que se vaya bajando se queda en blanco por que las lineas no las estas refrescando, ademas no hay por que refrescarlas, solo hay que refrescar los elementos que se mueven, todo lo demás será trabajo extra.

La solución esta en arreglar las llamadas a rand que creo que las estas haciendo mal. justo en esta linea: A.push_back(new AST(rand()&75 + 3, rand()&5 + 3));

...Tienes el borde de la pantalla que inicia a partir de la 4ª letra y lo mismo pasa con la parte de arriba, inicia en la 4ª linea.   si quieres hacer un rand que te funciones prueba eso:  bordeIzquierdo + rand() % bordeDerecho donde el borde derecho inicie dentro de ese "marco", creo que un 4 seria lo suyo. El borde derecho es lo que hace lo mismo pero impide que se salga por el lado derecho. En otras palabras... 4 + rand() % 75 hace que los asteroides inicien en la coordenada 4 y no pasen de la 74.

Ademas falto poner el srand() para que te genere valores aleatorios. te dejo el código como lo arregle y me funciono perfecto.

Quede claro que no mire nada más ;)

http://codepad.org/yNUTWY4K


Perfecto, ahora entiendo porque pasaba eso . Muchísimas gracias por tu tiempo y ya lo corregí:)