#include #include #include #include #include #include "Dyna_tbl.h" #include "..\libs\int_key\int_key.h" #include "..\modex\modex.h" #include "..\modex\c_utils.h" #define BORRAR 0 #define REescribe 1 #define CTE_SALTO 80 extern char prt_tbl[13+1][21+1]; extern char prt_tbl2[13+1][21+1]; extern "C" void SET_VECTORES(volatile char *); extern "C" void UNSET_VECTORES(void); void limpia_teclado(void); int RellanaConcursantes(void); void ProcesaMovimientos(int Page); void EscribeObjetos( int Accion, int Page ); void LiberaConcursantes(void); // Establece preferencias por defecto PREFERENCIAS Pref = { POS_BOSQUE, 4, { { t_d, t_g, t_r, t_f, t_tab }, { t_4n, t_6n, t_8n, t_2n, t_0n }, { t_d, t_g, t_r, t_f , t_tab }, { t_izquierda, t_derecha, t_arriba, t_abajo , t_0n } /* { t_d, t_g, t_r, t_f }, { t_d, t_g, t_r, t_f }, { t_d, t_g, t_r, t_f }, { t_d, t_g, t_r, t_f }, */ } }; volatile char mapa_teclado[512]; int RellanaConcursantes(void); struct byte { int PuedeMatar : 1 ; // Informa sobre si puede matar por contacto int PuedeMorir : 1 ; // Informa sobre si puede morir por contacto int PuedeVolar : 1 ; // Informa sobre si puede atravezar los cuadros int Dispara : 1 ; // Informa si el concursante puede disparar int CaputDelTo : 1 ; // Informa si el concursante puede disparar int Vidas : 4 ; // Vidas del concursante <= 4 }; // Esta estructura contendra todo lo que hay que procesar: // (todo lo que se mueva) jugadores, enemigos, bombas, teleports // // NOTA: Las primeras estructuras deben corresponder a los HUMANOS // tantas como participantes hubiesen... typedef struct concursantes { char Tipo_de_concursante; // Quien Juega char InfoConcursante; int PosX, PosY; // Posicion del concursante int old_PosX[2], old_PosY[2]; // Posiciones del concursante en cada pagina char Direccion; // Direccion que toma el concursante char Velocidad; // Como de rapido se mueve char delay_time; // Tiempo de retraso por el que va int secuencia_animada; // Secuencia de animaci¢n por la que va char Disparos; // # de disparos que puede poner al mismo tiempo long DisparosP; // # de disparos ya puestos char Longitud; // Longitud del disparo en cuadros; struct byte Varios; struct concursantes *poseed; // Due¤o f¡sico de este objeto... struct concursantes *sig; // Puntero al siguientes concursante } CONCURSANTES; CONCURSANTES *Concursantes; CONCURSANTES *NuevoConcursante(struct concursantes *Concur); //struct concursante *NuevoConcursante(struct concursantes *Concur); void GeneraFuego( CONCURSANTES *aux ); void GeneraXYaleatorio( int *X, int *Y ); void ColocaBomba( CONCURSANTES *concursante ); CONCURSANTES *EliminaConcursante(struct concursantes *Concur); void CompruebaCoordenadas(char incX, char incY, CONCURSANTES *objeto, char *Objeto_Caput ); void MovimientoAutomatico( CONCURSANTES *aux, char *incY, char *incX, int Page ); void ColocaFuego( int PosX, int PosY, CONCURSANTES *aux ); int jklop = 0; extern CallBIOSHandler; clock_t TiempoDeJuego, InicioDeJuego; void ComienzaJuego(void) { int Current_Page = 0, cifraTMP; long DTiempo; limpia_teclado(); if ( RellanaConcursantes() == ERROR ) Error(0x30); set_display_page( 1 ); CallBIOSHandler = 0; InicioDeJuego = clock(); while( mapa_teclado[t_esc] == 0 ) { //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ // mostramos el reloj... TiempoDeJuego = clock(); DTiempo = ( TiempoDeJuego - InicioDeJuego ) / CLK_TCK; // minutos cifraTMP = ( DTiempo / 60 ); tdraw_bitmap ((char far *)( (Sprite[POS_NUMEROS].Sprite[0])+(long)16*18*( cifraTMP / 10 ) ) , 28 + 16*0, 3, 16, 11); cifraTMP = ( cifraTMP - ( cifraTMP / 10 ) * 10 ); tdraw_bitmap ((char far *)( (Sprite[POS_NUMEROS].Sprite[0])+(long)16*18*cifraTMP ) , 28 + 16*1, 3, 16, 11); // minutos cifraTMP = ( DTiempo % 60 ); tdraw_bitmap ((char far *)( (Sprite[POS_NUMEROS].Sprite[0])+(long)16*18*( cifraTMP / 10 ) ) , 28 + 4 + 16*2, 3, 16, 11); cifraTMP = ( cifraTMP - ( cifraTMP / 10 ) * 10 ); tdraw_bitmap ((char far *)( (Sprite[POS_NUMEROS].Sprite[0])+(long)16*18*( cifraTMP ) ) , 28 + 4 + 16*3, 3, 16, 11); //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ if ( mapa_teclado[t_2] ) { mapa_teclado[t_2] = 0; set_display_page (2); sleep(5); } if ( mapa_teclado[t_9] ) { Pref.Entorno+=9; mapa_teclado[t_9] = 0; if ( Pref.Entorno >= POS_BOSQUE + 3*9 ) Pref.Entorno = POS_BOSQUE; } if ( mapa_teclado[t_0] ) { InicializaJuego(); mapa_teclado[t_0] = 0; copy_page( 2, 1 ); copy_page( 2, 0 ); } set_active_page (Current_Page); EscribeObjetos( BORRAR, Current_Page ); // copy_page( 2, Current_Page ); ProcesaMovimientos( Current_Page ); EscribeObjetos( REescribe, Current_Page ); set_display_page (Current_Page); Current_Page = Current_Page ^ 0x01; }; LiberaConcursantes(); } /**************************************************************************\ |* *| |* EscribeObjetos *| |* *| |* Descripci¢n: *| |* Se encarga de escribir todos los objetos a la patalla: *| |* a> se eliminan todos los objetos animados de la pantalla *| |* b> se dibujan en las nuevas posiciones *| |* *| |* Entradas: BORRA ------> a *| |* REescribe --> b *| |* Salidas: (ninguna) *| |* *| \**************************************************************************/ void EscribeObjetos( int Accion, int Page ) { CONCURSANTES *aux; int Ancho, Alto; // Empiezo por el principio aux = Concursantes; // Y mientras quede algo que procesar while( aux != NULL ) { // Obtengo las dimensiones Ancho = InfoSprites[ aux -> InfoConcursante ].Ancho; Alto = InfoSprites[ aux -> InfoConcursante ].Alto; if ( Accion == BORRAR ) copy_bitmap (2, aux -> old_PosX[Page] + 12+InfoSprites[aux -> InfoConcursante].CorrX, aux -> old_PosY[Page] + 20+InfoSprites[aux -> InfoConcursante].CorrY, aux -> old_PosX[Page]+12+Ancho+InfoSprites[aux -> InfoConcursante].CorrX, aux -> old_PosY[Page]+20+Alto+InfoSprites[aux -> InfoConcursante].CorrY, Page, aux -> old_PosX[Page] + 12+InfoSprites[aux -> InfoConcursante].CorrX, aux -> old_PosY[Page] + 20+InfoSprites[aux -> InfoConcursante].CorrY); // copy_bitmap (2, aux -> old_PosX[Page] + 12, aux -> old_PosY[Page] + 20, aux -> old_PosX[Page]+12+Ancho, aux -> old_PosY[Page]+20+Alto, // Page, aux -> old_PosX[Page] + 12, aux -> old_PosY[Page] + 20); else { // Amplio la secuencia animada // 0 Izq, 1 Der, 2 Arr, 3 Abj, Muerte tdraw_bitmap ((char far *)( (Sprite[aux -> Tipo_de_concursante].Sprite[ aux -> InfoConcursante == SPR_BAQUERO ? 0 : aux->Direccion ])+(long)Ancho*Alto* (long)( aux->secuencia_animada ) ), aux -> PosX+12+InfoSprites[aux -> InfoConcursante].CorrX, aux -> PosY+20+InfoSprites[aux -> InfoConcursante].CorrY, Ancho, Alto); // tdraw_bitmap ((char far *)( (Sprite[aux -> Tipo_de_concursante].Sprite[aux->Direccion])+(long)Ancho*Alto* (long)( aux->secuencia_animada ) ), aux -> PosX+12, aux -> PosY+20, Ancho, Alto); } aux = aux -> sig; }; } /**************************************************************************\ |* *| |* ProcesaMovimientos *| |* *| |* Descripci¢n: *| |* Genera los movimientos del HUMANO y maquina, despues *| |* llama a la funci¢n que los corrige... *| |* *| |* Entradas: Pagina de los movimientos *| |* Salidas: (ninguna) *| |* *| \**************************************************************************/ void ProcesaMovimientos(int Page) { CONCURSANTES *aux; char old_dir, enc; char incX, incY, objeto_caput; // Empiezo por el principio aux = Concursantes; // Y mientras quede algo que procesar while( aux != NULL ) { incX = incY = enc = objeto_caput = 0; old_dir = aux -> Direccion; // SOLO SE PROCESA SI ESTA VIVO if ( aux -> Direccion != 4 ) { switch( aux -> Tipo_de_concursante ) { // Los jugadores procesan sus movimientos segun el usuario // izq, der, arr, abj case POS_JUGADORa: case POS_JUGADORb: // Izquierda if ( mapa_teclado[Pref.Teclas[(aux -> Tipo_de_concursante)-POS_JUGADORa][0]] ) { incX = - (aux -> Velocidad); aux -> Direccion = 0; enc = 1; } else // Derecha if ( mapa_teclado[Pref.Teclas[(aux -> Tipo_de_concursante)-POS_JUGADORa][1]] ) { incX = (aux -> Velocidad); aux -> Direccion = 1; enc = 1; } else // Arriba if ( mapa_teclado[Pref.Teclas[(aux -> Tipo_de_concursante)-POS_JUGADORa][2]] ) { incY = - (aux -> Velocidad); aux -> Direccion = 2; enc = 1; } else // Abajo if ( mapa_teclado[Pref.Teclas[(aux -> Tipo_de_concursante)-POS_JUGADORa][3]] ) { incY = (aux -> Velocidad); aux -> Direccion = 3; enc = 1; } //else // Bomba if ( mapa_teclado[Pref.Teclas[(aux -> Tipo_de_concursante)-POS_JUGADORa][4]] ) { // Si puede disparar y el n§ de disparos puestos es menor al que tiene if ( aux -> Varios.Dispara && aux -> DisparosP < aux -> Disparos ) { mapa_teclado[Pref.Teclas[(aux -> Tipo_de_concursante)-POS_JUGADORa][4]] = 0; ColocaBomba( aux ); } } break; case POS_JUGADORd: case POS_JUGADORc: MovimientoAutomatico( aux, &incY, &incX, Page ); enc = 1; break; // La bomba no se mueve ( A menos que se encuentre en una zona deslizante case POS_BOMBA: // Eliminamos la bomba if ( (clock() - (aux -> DisparosP))/CLK_TCK >= aux -> Varios.Vidas ) objeto_caput = 1; enc = 1; break; case POS_BAQUERO: MovimientoAutomatico( aux, &incY, &incX, Page ); enc = 1; break; // El resto sigue un algoritmo de movimiento ( actualmente ninguno ); default: MovimientoAutomatico( aux, &incY, &incX, Page ); enc = 1; break; } // Procesa las coordenadas si no esta caput ( Direccion 4 ) CompruebaCoordenadas( incX, incY, aux, &objeto_caput ); // Cambia de secuencia animada si corresponde if ( enc ) { // Empieza el nuevo movimiento por por 0 si es distinto if ( aux -> Direccion != old_dir ) { aux -> secuencia_animada = 0; aux -> delay_time = 0; } else if ( (aux -> delay_time = aux -> delay_time + aux -> Velocidad) >= InfoSprites[ aux -> InfoConcursante ].PixelCambio ) { aux -> delay_time = 0; if ( (int)( aux -> secuencia_animada ) >= InfoSprites[ aux -> InfoConcursante ].Movimientos[ aux -> InfoConcursante == SPR_BAQUERO ? 0 : aux->Direccion] - 1 ) aux -> secuencia_animada = 0; else aux -> secuencia_animada = aux -> secuencia_animada + 1; } } }else{ if ( aux -> secuencia_animada >= (InfoSprites[ aux -> InfoConcursante ].Movimientos[4] - 1) ) aux -> Varios.CaputDelTo = 1; else if ( (TiempoDeJuego/*clock()*/ - aux -> DisparosP)>>1 >= 1 ) { aux -> DisparosP = TiempoDeJuego;//clock(); aux -> secuencia_animada = aux -> secuencia_animada + 1; } } // Copia los movimientos a la pagina adecuada aux -> old_PosX[Page] = aux -> PosX; aux -> old_PosY[Page] = aux -> PosY; if ( objeto_caput ) { if ( aux -> Tipo_de_concursante == POS_BOMBA ) { aux -> Varios.Vidas = 0; aux -> Varios.CaputDelTo = 1; GeneraFuego( aux ); } else { aux -> Varios.Vidas = aux -> Varios.Vidas - 1; aux -> Direccion = 4; // Activamos la muerte aux -> secuencia_animada = 0; aux -> DisparosP = TiempoDeJuego; } } if ( aux -> Varios.CaputDelTo ) { // Borramos al objeto de la pantalla incX = InfoSprites[ aux -> InfoConcursante ].Ancho; incY = InfoSprites[ aux -> InfoConcursante ].Alto; if ( aux -> InfoConcursante == SPR_FUEGO ) { set_active_page (2); aux -> DisparosP = (Pref.Entorno+4); draw_bitmap ((char far*)( Sprite[POS_ELEM_MAPA].Sprite[0] + /*incX * incY **/((aux -> DisparosP)<<8) ), aux -> PosX + 12 , aux -> PosY + 20, incX, incY ); set_active_page (Page); draw_bitmap ((char far*)( Sprite[POS_ELEM_MAPA].Sprite[0] + /*incX * incY **/((aux -> DisparosP)<<8) ), aux -> PosX + 12 , aux -> PosY + 20, incX, incY ); } copy_bitmap (2, aux -> old_PosX[!Page] + 12+InfoSprites[aux -> InfoConcursante].CorrX, aux -> old_PosY[!Page] + 20+InfoSprites[aux -> InfoConcursante].CorrY, aux -> old_PosX[!Page]+12+incY+InfoSprites[aux -> InfoConcursante].CorrX, aux -> old_PosY[!Page]+20+incY+InfoSprites[aux -> InfoConcursante].CorrY, !Page, aux -> old_PosX[!Page] + 12+InfoSprites[aux -> InfoConcursante].CorrX, aux -> old_PosY[!Page] + 20+InfoSprites[aux -> InfoConcursante].CorrY); prt_tbl[(aux -> PosY)/16][(aux -> PosX)/16] = 0; if ( ( aux -> poseed ) != NULL ) ( ( aux -> poseed ) -> DisparosP ) --; aux = EliminaConcursante( aux ); } else aux = aux -> sig; }; } void GeneraFuego( CONCURSANTES *concursante ) { int x, y, inc; CONCURSANTES *aux; x = concursante -> PosX / 16; y = concursante -> PosY / 16; // Scaneamos posibiliades hacia la izquierda for ( inc = 1; ( x - inc ) >= 0 && inc <= concursante -> Longitud; inc++ ) if ( prt_tbl[y][x-inc] != 1 && prt_tbl[y][x-inc] != 2 ) { if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1); aux -> Tipo_de_concursante = POS_FUEGOh; ColocaFuego( (x-inc)*16, y*16, aux ); prt_tbl[y][x-inc] = 4; } else { // Si es una bomba ­­­ BOOM !!! ( la otra ) if ( prt_tbl2[y][x-inc] == 0 ) { if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1); aux -> Tipo_de_concursante = POS_FUEGOh; ColocaFuego( (x-inc)*16, y*16, aux ); prt_tbl[y][x-inc] = 4; } break; } // Scaneamos posibiliades hacia la Derecha for ( inc = 1; ( x + inc ) < 21 && inc <= concursante -> Longitud; inc++ ) if ( prt_tbl[y][x+inc] != 1 && prt_tbl[y][x+inc] != 2 ) { if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1); aux -> Tipo_de_concursante = POS_FUEGOh; ColocaFuego( (x+inc)*16, y*16, aux ); prt_tbl[y][x+inc] = 4; } else { // Si es una bomba ­­­ BOOM !!! ( la otra ) if ( prt_tbl2[y][x+inc] == 0 ) { if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1); aux -> Tipo_de_concursante = POS_FUEGOh; ColocaFuego( (x+inc)*16, y*16, aux ); prt_tbl[y][x+inc] = 4; } break; } // Scaneamos posibiliades hacia la arriba for ( inc = 1; ( y - inc ) >= 0 && inc <= concursante -> Longitud; inc++ ) if ( prt_tbl[y-inc][x] != 1 && prt_tbl[y-inc][x] != 2 ) { if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1); aux -> Tipo_de_concursante = POS_FUEGOv; ColocaFuego( x*16, (y-inc)*16, aux ); prt_tbl[y-inc][x] = 4; } else { // Si es una bomba ­­­ BOOM !!! ( la otra ) if ( prt_tbl2[y-inc][x] == 0 ) { if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1); aux -> Tipo_de_concursante = POS_FUEGOv; ColocaFuego( x*16, (y-inc)*16, aux ); prt_tbl[y-inc][x] = 4; } break; } // Scaneamos posibiliades hacia la abajo for ( inc = 1; ( y + inc ) < 13 && inc <= concursante -> Longitud; inc++ ) if ( prt_tbl[y+inc][x] != 1 && prt_tbl[y+inc][x] != 2 ) { if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1); aux -> Tipo_de_concursante = POS_FUEGOv; ColocaFuego( x*16, (y+inc)*16, aux ); prt_tbl[y+inc][x] = 4; } else { // Si es una bomba ­­­ BOOM !!! ( la otra ) if ( prt_tbl2[y+inc][x] == 0 ) { if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1); aux -> Tipo_de_concursante = POS_FUEGOv; ColocaFuego( x*16, (y+inc)*16, aux ); prt_tbl[y+inc][x] = 4; } break; } } void ColocaFuego( int PosX, int PosY, CONCURSANTES *aux ) { aux -> InfoConcursante = SPR_FUEGO; aux -> PosX = PosX; aux -> PosY = PosY; aux -> old_PosX[0] = aux -> old_PosX[1] = PosX; aux -> old_PosY[0] = aux -> old_PosY[1] = PosY; aux -> Direccion = 4; aux -> Velocidad = 1; aux -> delay_time = 40; aux -> secuencia_animada = 0; aux -> poseed = NULL; aux -> DisparosP = TiempoDeJuego; aux -> Varios.CaputDelTo = 0; } void MovimientoAutomatico( CONCURSANTES *aux, char *incY, char *incX, int Page ) { // Cambiamos de direccion if ( aux -> old_PosX[Page] == aux -> PosX && aux -> old_PosY[Page] == aux -> PosY ) { aux -> Direccion = (char)random_int( 4 ); } switch( aux -> Direccion ) { // izq, der, arr, abj case 0: *incX = -(aux -> Velocidad); break; case 1: *incX = (aux -> Velocidad); break; case 2: *incY = -(aux -> Velocidad); break; case 3: *incY = (aux -> Velocidad); break; } } /**************************************************************************\ |* *| |* CompruebaCoordenadas *| |* *| |* Descripci¢n: *| |* Comprueba que las coordenadas son correctas, en caso *| |* contrario las corrige. Tambien procesa el caso de *| |* encontrarse en una zona especial: teleport, flecha... *| |* *| |* Entradas: Punteros a las Coordenadas X , Y *| |* Salidas: (ninguna) *| |* *| \**************************************************************************/ void CompruebaCoordenadas( char incX, char incY, CONCURSANTES *objeto, char *Objeto_Caput ) { int xV, yV, xS, yS, Tmp; // Este es el puntero donde estan los cuadros: // prt_tbl[13][21]; // // 1 ---> Cuadro indestructible / BOMBA // 2 ---> Cuadro destructible ( Se puede sobrevolar ) // 3 ---> Objeto que puede matar al contacto // ( Solo los jugadores pueden morir al contacto ) // Compruebo que no este fuera de los bordes while ( (objeto->PosX) < 0 ) (objeto->PosX)++; while ( (objeto->PosX) > 16*20 ) (objeto->PosX)--; while ( (objeto->PosY) < 0 ) (objeto->PosY)++; while ( (objeto->PosY) > 16*12 ) (objeto->PosY)--; // xV = (*x + incX)/16; yV = (*y + incY)/16; // Es un movimiento en el eje X if ( incX != 0 ) { xV = ((objeto->PosX) + (incX < 0 ? 2 : 11 ) )/16; yV = ((objeto->PosY)+2)/16; Tmp = ((objeto->PosY)+11)/16; // Si no es un jugador ni una bomba ( Controlamos su c¢digo 3 ) xS = xV; yS = yV; if ( prt_tbl[yS][xS] == 4 ) *Objeto_Caput = 1; if ( objeto -> Varios.PuedeMatar ) { prt_tbl[yV][xV] = 0; } // Si estoy pisando un cuadro ocupado seguimos una estructura distinta if ( prt_tbl[yV][xV] == 1 ) //!= 0 ) if ( incX < 0 ) xV --; else xV ++; else xV = ((objeto->PosX) + (incX < 0 ? 2 : 11 ) + incX )/16; // Cuidadin que puede morir // if ( ( objeto -> InfoConcursante) == SPR_JUGADOR && ( objeto -> Varios.PuedeMorir ) && ( prt_tbl[yV][xV] == 3 || prt_tbl[Tmp][xV] == 3 ) ) /* if ( prt_tbl[yS][xS] == 4 ) *Objeto_Caput = 1; else */ if ( ( objeto -> InfoConcursante) == SPR_JUGADOR && ( objeto -> Varios.PuedeMorir ) && prt_tbl[yS][xS] == 3 ) *Objeto_Caput = 1; else if ( prt_tbl[yV][xV] == 0 && prt_tbl[Tmp][xV] == 0 || ( objeto -> Varios.PuedeVolar && prt_tbl[yV][xV] == 2 && prt_tbl[Tmp][xV] == 2 ) ) { (objeto->PosX) = (objeto->PosX) + incX; // Si no es un jugador ni una bomba ( Controlamos su c¢digo 3 ) if ( objeto -> Varios.PuedeMatar ) prt_tbl[yV][xV] = 3; } else { // Si no es un jugador ni una bomba ( Controlamos su c¢digo 3 ) if ( objeto -> Varios.PuedeMatar ) prt_tbl[yS][xS] = 3; } } else // Es un movimiento en el eje Y if ( incY != 0 ) { yV = ((objeto->PosY) + (incY < 0 ? 2 : 11 ) )/16; xV = ((objeto->PosX)+2)/16; Tmp = ((objeto->PosX)+11)/16; // Si no es un jugador ni una bomba ( Controlamos su c¢digo 3 ) xS = xV; yS = yV; if ( prt_tbl[yS][xS] == 4 ) *Objeto_Caput = 1; if ( objeto -> Varios.PuedeMatar ) { prt_tbl[yV][xV] = 0; } // Si estoy pisando un cuadro ocupado seguimos una estructura distinta if ( prt_tbl[yV][xV] == 1 )//!= 0 ) if ( incY < 0 ) yV --; else yV ++; else yV = ((objeto->PosY) + (incY < 0 ? 2 : 11 ) + incY )/16; // Cuidadin que puede morir // if ( ( objeto -> InfoConcursante) == SPR_JUGADOR && ( objeto -> Varios.PuedeMorir ) && ( prt_tbl[yV][xV] == 3 || prt_tbl[yV][Tmp] == 3 ) ) /* if ( prt_tbl[yS][xS] == 4 ) *Objeto_Caput = 1; else */ if ( ( objeto -> InfoConcursante) == SPR_JUGADOR && ( objeto -> Varios.PuedeMorir ) && prt_tbl[yS][xS] == 3 ) *Objeto_Caput = 1; else if ( prt_tbl[yV][xV] == 0 && prt_tbl[yV][Tmp] == 0 || ( objeto -> Varios.PuedeVolar && prt_tbl[yV][xV] == 2 && prt_tbl[yV][Tmp] == 2 ) ) { (objeto->PosY) = (objeto->PosY) + incY; // Si no es un jugador ni una bomba ( Controlamos su c¢digo 3 ) if ( objeto -> Varios.PuedeMatar ) prt_tbl[yV][xV] = 3; } else { // Si no es un jugador ni una bomba ( Controlamos su c¢digo 3 ) if ( objeto -> Varios.PuedeMatar ) prt_tbl[yS][xS] = 3; } } else { // No se mueve, pero puede estar tocandole algo que le mate xS = ((objeto->PosX)+2)/16; yS = ((objeto->PosY)+2)/16; if ( prt_tbl[yS][xS] == 4 ) *Objeto_Caput = 1; else if ( ( objeto -> InfoConcursante) == SPR_JUGADOR && ( objeto -> Varios.PuedeMorir ) && prt_tbl[yS][xS] == 3 ) *Objeto_Caput = 1; } // Por que lado del que pisa esta ocupado ³ // | ³ // ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄÄÄÄÄÄÄ¿ // ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ <Ä ³ _ ³ // ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÄÄÄij |Ù ³ // ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ³ ³ // ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÀÄÄÄÄÄÄÄÙ // ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ // ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ // ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ // ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ // ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ // ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ ÚÄ¿ // ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ ÀÄÙ // }; /**************************************************************************\ |* *| |* limpia_teclado *| |* *| |* Descripci¢n: *| |* Limpia el buffer propio de teclado *| |* *| |* Entradas: (ninguna) *| |* Salidas: (ninguna) *| |* *| \**************************************************************************/ void limpia_teclado(void) { int n; for(n=0; n<256; n++) mapa_teclado[n]=0; } void ColocaBomba( CONCURSANTES *concursante ) { CONCURSANTES *aux; int xV, yV; xV = (concursante -> PosX + 8)/16; yV = (concursante -> PosY + 8)/16; if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1); aux -> Varios.PuedeMatar = 1; aux -> Varios.PuedeMorir = 1; aux -> Varios.PuedeVolar = 1; aux -> Varios.Dispara = 1; aux -> Varios.Vidas = 5; // Vida de la bomba == 5sg. aux -> Tipo_de_concursante = POS_BOMBA; aux -> InfoConcursante = SPR_BOMBA; aux -> PosX = xV*16; aux -> PosY = yV*16; prt_tbl[yV][xV] = 1; // Tipo 1 == indestructible aux -> old_PosX[0] = aux -> old_PosX[1] = xV; aux -> old_PosY[0] = aux -> old_PosY[1] = yV; aux -> Direccion = 0; aux -> Velocidad = 1; aux -> delay_time = 40; aux -> secuencia_animada = 0; aux -> poseed = concursante; aux -> DisparosP = clock(); aux -> Longitud = concursante -> Longitud; concursante -> DisparosP = concursante -> DisparosP + 1; aux -> Varios.CaputDelTo = 0; } /**************************************************************************\ |* *| |* RellenaConcursantes *| |* *| |* Descripci¢n: *| |* Se encarga de colocar y definir a los concursantes *| |* *| |* Entradas: (ninguna) *| |* Salidas: OK todo va bien *| |* ERROR algo va mal *| |* *| \**************************************************************************/ int RellanaConcursantes(void) { CONCURSANTES *aux; // Jugador 1 if ( (Concursantes = aux = NuevoConcursante(Concursantes)) == NULL ) return ERROR; aux -> Varios.PuedeMatar = 0; aux -> Varios.PuedeMorir = 1; aux -> Varios.PuedeVolar = 0; aux -> Varios.Dispara = 1; aux -> Varios.Vidas = 1; aux -> Tipo_de_concursante = POS_JUGADORa; aux -> InfoConcursante = SPR_JUGADOR ; aux -> PosX = 0; aux -> PosY = 0; aux -> old_PosX[0] = aux -> old_PosX[1] = 0; aux -> old_PosY[0] = aux -> old_PosY[1] = 0; aux -> Direccion = 2; aux -> Velocidad = 1; aux -> delay_time = 40; aux -> secuencia_animada = 0; aux -> Disparos = 5; aux -> Longitud = 3; aux -> DisparosP = 0; aux -> poseed = NULL; aux -> Varios.CaputDelTo = 0; // Jugador 2 if ( (aux = NuevoConcursante(Concursantes)) == NULL ) return ERROR; aux -> Varios.PuedeMatar = 0; aux -> Varios.PuedeMorir = 1; aux -> Varios.PuedeVolar = 0; aux -> Varios.Dispara = 1; aux -> Varios.Vidas = 1; aux -> Tipo_de_concursante = POS_JUGADORb; aux -> InfoConcursante = SPR_JUGADOR ; aux -> PosX = 320; aux -> PosY = 192; aux -> old_PosX[0] = aux -> old_PosX[1] = 320; aux -> old_PosY[0] = aux -> old_PosY[1] = 192; aux -> Direccion = 2; aux -> Velocidad = 1; aux -> delay_time = 40; aux -> secuencia_animada = 0; aux -> Disparos = 3; aux -> Longitud = 3; aux -> DisparosP = 0; aux -> poseed = NULL; aux -> Varios.CaputDelTo = 0; // Jugador 3 if ( Pref.Jugadores >= 3 ) { if ( (aux = NuevoConcursante(Concursantes)) == NULL ) return ERROR; aux -> Varios.PuedeMatar = 0; aux -> Varios.PuedeMorir = 1; aux -> Varios.PuedeVolar = 0; aux -> Varios.Dispara = 1; aux -> Varios.Vidas = 1; aux -> Tipo_de_concursante = POS_JUGADORc; aux -> InfoConcursante = SPR_JUGADOR ; aux -> PosX = 320; aux -> PosY = 0; aux -> old_PosX[0] = aux -> old_PosX[1] = 320; aux -> old_PosY[0] = aux -> old_PosY[1] = 0; aux -> Direccion = 2; aux -> Velocidad = 1; aux -> delay_time = 40; aux -> secuencia_animada = 0; aux -> Disparos = 1; aux -> Longitud = 1; aux -> poseed = NULL; aux -> Varios.CaputDelTo = 0; } // Jugador 4 if ( Pref.Jugadores >= 4 ) { if ( (aux = NuevoConcursante(Concursantes)) == NULL ) return ERROR; aux -> Varios.PuedeMatar = 0; aux -> Varios.PuedeMorir = 1; aux -> Varios.PuedeVolar = 0; aux -> Varios.Dispara = 1; aux -> Varios.Vidas = 1; aux -> Tipo_de_concursante = POS_JUGADORd; aux -> InfoConcursante = SPR_JUGADOR ; aux -> PosX = 0; aux -> PosY = 192; aux -> old_PosX[0] = aux -> old_PosX[1] = 0; aux -> old_PosY[0] = aux -> old_PosY[1] = 192; aux -> Direccion = 2; aux -> Velocidad = 1; aux -> delay_time = 40; aux -> secuencia_animada = 0; aux -> Disparos = 1; aux -> Longitud = 1; aux -> DisparosP = 0; aux -> poseed = NULL; aux -> Varios.CaputDelTo = 0; } // Vaquero if ( (aux = NuevoConcursante(Concursantes)) == NULL ) return ERROR; aux -> Varios.PuedeMatar = 1; aux -> Varios.PuedeMorir = 1; aux -> Varios.PuedeVolar = 0; aux -> Varios.Dispara = 0; aux -> Varios.Vidas = 1; aux -> Tipo_de_concursante = POS_BAQUERO; aux -> InfoConcursante = SPR_BAQUERO; GeneraXYaleatorio( &(aux -> PosX), &(aux -> PosY) ); aux -> old_PosX[0] = aux -> old_PosX[1] = 0; aux -> old_PosY[0] = aux -> old_PosY[1] = 192; aux -> Direccion = 2; aux -> Velocidad = 1; aux -> delay_time = 40; aux -> secuencia_animada = 0; aux -> Disparos = 1; aux -> Longitud = 1; aux -> DisparosP = 0; aux -> poseed = NULL; aux -> Varios.CaputDelTo = 0; return OK; } void GeneraXYaleatorio( int *X, int *Y ) { do { *X = random_int( 17 ) + 2; *Y = random_int( 9 ) + 2; }while( prt_tbl[*Y][*X] == 1 ); prt_tbl[*Y][*X] = 0; *X = *X * 16; *Y = *Y * 16; } /**************************************************************************\ |* *| |* LiberaConcursantes *| |* *| |* Descripci¢n: *| |* Elimina a todos los concursantes liberando la memoria *| |* *| |* Entradas: (ninguna) *| |* Salidas: (ninguna) *| |* *| \**************************************************************************/ void LiberaConcursantes(void) { CONCURSANTES *aux; aux = Concursantes; if ( Concursantes -> sig != NULL ) { Concursantes = Concursantes -> sig; LiberaConcursantes(); } free( aux ); } /**************************************************************************\ |* *| |* EliminaConcursante *| |* *| |* Descripci¢n: *| |* Elimina al concursante que se le pasa como par metro *| |* *| |* Entradas: El puntero al elemento a eliminar *| |* Salidas: Elemento siguiente en la lista *| |* *| \**************************************************************************/ CONCURSANTES *EliminaConcursante(CONCURSANTES *Concur) { CONCURSANTES *ant; CONCURSANTES *aux; ant = aux = Concursantes; // Quizas haya que eliminar al primer elemento if ( aux == Concur ) { Concursantes = aux -> sig; free ( Concur ); return Concursantes; } else { while ( aux != Concur && aux != NULL) { ant = aux; aux = aux -> sig; }; if ( aux == NULL ) return NULL; ant -> sig = Concur -> sig; free( Concur ); return (ant -> sig); } } /**************************************************************************\ |* *| |* NuevoConcursante *| |* *| |* Descripci¢n: *| |* A¤ade un nuevo concursante al final *| |* *| |* Entradas: El puntero base donde insertar (Busca solo el final) *| |* *| |* Salidas: direccion del concursante a¤adido *| |* NULL algo va mal *| |* *| \**************************************************************************/ CONCURSANTES *NuevoConcursante(CONCURSANTES *Concur) { CONCURSANTES *aux, *Concursante; if ( (aux = (CONCURSANTES *)malloc( sizeof(CONCURSANTES) ) ) == NULL ) return NULL; Concursante = Concur; aux -> sig = NULL; // Todavia no hay concursantes if ( Concursante == NULL ) { Concursante = aux; } else { while( Concursante -> sig != NULL ) Concursante = Concursante -> sig; Concursante -> sig = aux; } return aux; }