branzitu
Registrado: 11 Abr 2014 Mensajes: 1
| Publicado: 11/04/2014 5:37 am | | | Título: Conflicto en minijuego de naves |
| 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),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. |
|