• Miércoles 20 de Noviembre de 2024, 16:22

Autor Tema:  Conflicto en juego de naves  (Leído 2063 veces)

branzitu

  • Nuevo Miembro
  • *
  • Mensajes: 1
    • Ver Perfil
Conflicto en juego de naves
« en: Martes 15 de Abril de 2014, 16:56 »
0
He estado trabajando en un minijuego de naves en c++ para iniciarme de forma autodidacta en el mundo de la programacion de videojuegos empezando por la base. Pero bueno, mi problema es el siguiente: Todo iba correcto cuando metí los bucles y lineas de codigos para el movimiento de la nave. Cuando le metí un metodo con kbhit para que la nave disparase, la nave dispara correctamente, pero hay problemas en el movimiento de la nave. Esto ocurre cuando el bucle de codigo del disparo de la nave está situado por encima del codigo fuente del movimiento de la nave. Si los situamos a la inversa (primero el movimiento y luego el disparo) la nave se mueve correctamente pero tiene problemas en el disparo. Con lo que a problemas me refiero es que al intentar mover, se mueve en la direccion que le pedimos, pero en tiempos aleatorios, si haces la accion para mover 4 veces a lo mejor se mueve 1 vez o ninguna, y lo mismo con el disparo. A continuación pongo el código del programa:

// Videojuego de Naves
// Rubén Zerpa Rodríguez - 19/03/14

#include <stdio.h> //biblioteca para printf
#include <windows.h> //biblioteca de windows
#include <conio.h>
#include <stdlib.h>
#include <list>

using namespace std;

void gotoxy(int x, int y){//declaración de variables para las coordenadas
HANDLE rWin; //denominación para nuestra ventana
rWin = GetStdHandle (STD_OUTPUT_HANDLE); //valor de salida para nuestra rWin
COORD dwPos; //llamada a las coordenadas "x" e "y"
dwPos.X=x; //valor a las coordenadas
dwPos.Y=y;

SetConsoleCursorPosition(rWin, dwPos); //situar cursor en ventana rWin en coordenadas dwPos
}

void OcultarCursor(){ //declaracion de OcultarCursor
HANDLE rWin;
rWin = GetStdHandle (STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO rin; //denominacion de "rin" a la info del cursor
rin.dwSize = 100; //tamaño del cursor
rin.bVisible = FALSE; //visibilidad del cursor true o false
SetConsoleCursorInfo(rWin,&rin); //determinacion de los parapetros establecidos
}

void limites(){
for (int i=3; i<77; i++){ //funcion para recorrer limites en x
gotoxy(i,2); printf("%c",205);
gotoxy(i,32); printf("%c",205);
}
for (int j=3; j<32; j++){ //funcion para recorrer limites en y
gotoxy(3,j); printf("%c",186); //linea recta de limites
gotoxy(76,j); printf("%c",186);
}
gotoxy(3,2); printf("%c",201); //esquinas
gotoxy(76,32); printf("%c",188);
gotoxy(76,2); printf("%c",187);
gotoxy(3,32); printf("%c",200);
}

class NAVE{ //definicion de una clase para la nave
int x,y; //valores de coordenadas de "x" e "y"
int corazones; //variable para los corazones
int vidas;
public: //funcion accesible desde fuera del class
NAVE(int _x, int _y, int _corazones, int _vidas): x(_x),y(_y),corazones(_corazones), vidas(_vidas){} //constructor y parametros
int X(){return x;} // metodo para que fuera de la clase "Nave" se pueda acceder a "x" e "y"
int Y() {return y;}
void COR() {corazones--;} //funcion de decrecer los corazones
void forma(); //declaracion de funciones
void borrar();
void mover();
void heridas();
void muerte();
}; //despues de class poner siempre ;
void NAVE::forma(){//dibujo de la nave
gotoxy(x,y); printf(" %c%c%c ", 47,205,92);
gotoxy(x,y+1); printf("%c%c %c%c", 47,238,238,92);
gotoxy(x,y+2); printf("%c%c%c%c%c", 200,62,178,60,188);
}
void NAVE::borrar(){//funcion para borrar el asterisco en el momento en el que está, para evitar dejar rastro
gotoxy(x,y); printf(" ");
gotoxy(x,y+1); printf(" ");
gotoxy(x,y+2); printf(" ");
}
void NAVE::mover(){ //funcion para mover la nave
if (kbhit()){ //funcion de windows para evaluar si se presiona tecla
char tecla = getch(); //funcion para guardar la letra presionada
borrar(); //alusion a void NAVE::borrar
if(tecla == 'a' && x>4) x-=2; //bucle if para detectar tecla presionada y actuar en consecuencia
if(tecla == 'd' && x+7<77) x+=2; //se le ponen maximos y minimos para que no sobrepase limites
if(tecla == 'w' && y>4) y-=2; //el +7 y +3 son para que cuente a partir de lso valores mas a la derecha e izquierda
if(tecla == 's' && y+3<31) y+=2;
forma(); //alusion a void NAVE:forma
heridas(); //imprime las heridas en el momento del primer movimiento
}
}
void NAVE::heridas(){//funcion para las vidas
gotoxy(50,1); printf("Vidas %d",vidas); //imprime "vidas" y el numero de vidas
gotoxy(61,1); printf("Heridas");//ubicacion de la palabra vidas
gotoxy(69,1); printf(" ");//borrado del espacio seleccionado
for (int i=0; i<corazones; i++){//bucle for para las vidas
gotoxy(69+i,1); printf("%c",3);//imprenta de las vidas en el hueco seleccionado
}
}
void NAVE::muerte(){//funcion para cuando los corazones lleguen a 0, dibuje una explosion
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();
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;
heridas();
forma();
}
}

class AST{ //clase para los asteroides
int x,y;
public:
AST(int _x, int _y):x(_x),y(_y){}
void forma();
void mover();
void choque(class NAVE &nr); //en el momento del choque, referenciar a la nave
};
void AST::forma(){
gotoxy(x,y); printf("%c",169);
}
void AST::mover(){
gotoxy(x,y); printf(" ");
y++; //funcion para que el asteroide continue hacia abajo hasta el final
if (y>31){
x = rand()%72 + 4;
y = 4;
}
forma();
}
void AST::choque(class NAVE &nr){//funcion para el choque de asteroides
if( x >= nr.X() && x < nr.X()+5 && y >= nr.Y() && y <= nr.Y()+2){ //bucle para el choque en toda la superficie de la nave
nr.COR();
nr.forma();
nr.heridas();
x = rand()%71 + 4; //volver a lanzar el asteroide en una posicion aleatoria
y = 3;
}
}

class BALA{ //clase para balas
int x,y;
public:
BALA(int _x, int _y): x(_x),y(_y){}
int X(){ return x; }//valor de X retorna el valor de x
int Y(){ return y; }
void mover();
bool fuera(); //bool para detectar el limite del escenario
};
void BALA::mover(){
gotoxy(x,y); printf(" ");
y--; //mover la bala recto hacia arriba
gotoxy(x,y); printf("*");
}
bool BALA::fuera(){//funcion bool para detectar el limite
if(y == 3) return true;
return false;
}

int main() // funcion principal
{
OcultarCursor();
limites();
NAVE nr(38,28,3,3); //creacion de objeto "nr" y puesta en coordenadas x e y
nr.forma(); //llamada a la forma de la nave (metodo)


list<AST*> A;
list<AST*>::iterator itA;
for(int i=0; i<5; i++){
A.push_back(new AST(rand()%75 + 3, rand()%5 + 4));
}

list<BALA*> br;//lista de balas
list<BALA*>::iterator it; //iterador de las balas

bool game_over = false; //bucle para que el juego siga hasta que game over sea verdadero
while (!game_over){

ESTE ES EL DISPARO, QUE AL PONERLO DELANTE DE "MOVER", DISPARA CORRECTAMENTE

if(kbhit()){ //detectar la letra "k" y disparar bala
char tecla = getch(); //guardar las teclas en "tecla"
if(tecla == 'k'){
br.push_back(new BALA(nr.X() + 2, nr.Y() + 1));
}
}
for(it = br.begin(); it != br.end(); it++){
(*it) -> mover();
if((*it)->fuera()){
gotoxy((*it)->X(), (*it)->Y()); printf(" ");
delete(*it);//borrar it
it = br.erase(it); //volver a crear it en otra posicion
}
}

for(itA = A.begin(); itA != A.end(); itA++){
(*itA)->mover();
(*itA)->choque(nr);

}
ESTA ES LA LLAMADA, QUE AL PONERLA DETRAS DEL DISPARO, LA NAVE SE MUEVE MAL
nr.mover();//llamada a la funcion mover de la nave (metodo)
nr.muerte();
Sleep(30); //detener el proceso 30ms para evitar sobrecarda de procesador
}
return 0;
}

Lo siento si es muy lioso de ver desde aquí, no encontré la forma de insertar el codigo de forma mas limpia. Un saludo y muchas gracias por su atención.