Aplicacin de matemticas para juego: TiroAlPlato usando lenguaje de programacin.
Propsito: Elabora una aplicacin de videojuego del TiroAlPlato usando lenguaje de programacin para la aplicacin de conceptos de geometra plana. Introduccion En esta prctica se ver uno de los juegos ms conocidos, parecido al de disparar a patos, pero en esta ocasin son a platos, como se explica en el propsito de la prctica, se requiere utilizar de conocimientos matemticos para hacer el efecto de que el plato va volando por la pantalla. Se presenta a continuacin el cdigo utilizado, la explicacin del cdigo se vern en, los comentarios dentro del programa. Los comentarios se encuentran en color AZUL #include <stdlib.h> // Para "rand" #include <math.h> // Para "sqrt" #include <allegro.h> //Se declaran las constantes globales #define ANCHOPANTALLA 320 #define ALTOPANTALLA 200 #define MAXRADIODIANA 25 #define MINRADIODIANA 5 #define NUMDIANAS 12 #define MAXINCREMXDIANA 20 #define MININCREMXDIANA 10 #define RETARDO 7 //Declaramos las variables globales int TamanyoDianaActual, numDianaActual, posXdiana, posYdiana, radioDiana, incremXdiana, incremYdiana, acertado = 0; // Si se acierta -> plato nuevo long int puntos = 0, contadorActual = 0; float a,b,c; // Para la parbola del plato
//Ahora la rutina de inicializacin donde iniciamos en allegro e intentamos entrar a modo grfico... int inicializa() { allegro_init(); install_keyboard(); install_timer(); install_mouse(); if (set_gfx_mode(GFX_SAFE, ANCHOPANTALLA, ALTOPANTALLA, 0, 0) != 0) { set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); allegro_message( "Incapaz de entrar a modo grafico\n%s\n", allegro_error); return 1; } numDianaActual = 1; srand(time(0)); show_mouse(screen); return 0; } //Rutina para el nuevo nuevo plato void nuevoPlato() { int xVerticeParabola, yVerticeParabola; float pParabola; // Un radio al azar entre el valor mximo y el mnimo radioDiana = (rand() % (MAXRADIODIANA - MINRADIODIANA)) + MINRADIODIANA; // La velocidad (incremento de X), similar incremXdiana = (rand() % (MAXINCREMXDIANA - MININCREMXDIANA)) + MININCREMXDIANA; // Vrtice de la parbola, cerca del centro en horizontal xVerticeParabola = ANCHOPANTALLA/2 + (rand() % 40) - 20; // Y mitad superior de la pantalla, en vertical yVerticeParabola = (rand() % (ALTOPANTALLA/2));
// Calculo a, b y c de la parbola pParabola = ALTOPANTALLA/2; a = 1 / (2*pParabola); b = -xVerticeParabola / pParabola; c = ((xVerticeParabola*xVerticeParabola) / (2*pParabola) ) + yVerticeParabola; // Posicin horizontal: junto margen izquierdo posXdiana = radioDiana; // Posicin vertical: segn la parbola posYdiana = a*posXdiana*posXdiana + b*posXdiana + c; } //Redibujar pantalla... void redibujaPantalla() { // Oculto ratn scare_mouse(); // Se borra pantalla clear_bitmap(screen); // Sincronizo con barrido para menos parpadeos vsync(); // Se dibuja el paisaje a observar rectfill(screen,0,0,ANCHOPANTALLA,ALTOPANTALLA-40, makecol(70, 70, 255)); //Cielo textprintf(screen, font, 4,4, palette_color[11], "Puntos: %d", puntos); // Puntuacin rectfill(screen,0,ALTOPANTALLA-40,ANCHOPANTALLA,ALTOPANTALLA, makecol(0, 150, 0)); //Suelo circlefill(screen, posXdiana, posYdiana, radioDiana, palette_color[15]); // Diana if (numDianaActual <= NUMDIANAS) { textprintf(screen, font, 4,190, palette_color[10], "Platos: %d", NUMDIANAS-numDianaActual); } // Restantes, si no acab unscare_mouse(); } //Se establece la distancia entre dos puntos float distancia(int x1, int x2, int y1, int y2) { return (sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)) ); } //Rutina de temporizacin volatile long int contador = 0; void aumentaContador(void) { contador++; } END_OF_FUNCTION(aumentaContador); //Cuerpo del programa int main() { // Se inicializan los intentos if (inicializa() != 0) exit(1); // Bloqueamos la variable y la funcin del temporizador LOCK_ // En esta seccion se repite mientras se mueve VARIABLE( contador ); LOCK_FUNCTION( aumentaContador ); // Se pone el temporizador en marcha: cada 10 milisegundos install_int(aumentaContador, 10); do { // Ciclo que repite el codigo para cada plato nuevoPlato(); // Calculo su posicin inicial redibujaPantalla(); // Y dibujo la pantalla acertado = 0; // Todava no se ha acertado, claro do { // Compruebo el ratn if (mouse_b & 1) { if (distancia(mouse_x, posXdiana, mouse_y,posYdiana) <= radioDiana) { puntos += ANCHOPANTALLA-posXdiana; acertado = 1; } } // Si ya se ha pasado el retardo, muevo if (contador >= contadorActual+RETARDO) { contadorActual = contador+RETARDO; posXdiana += incremXdiana; posYdiana = a*posXdiana*posXdiana + b*posXdiana + c; redibujaPantalla(); } } while ((posXdiana <= ANCHOPANTALLA - radioDiana) && (acertado == 0)); numDianaActual ++; // Se coloca la siguiente diana } while (numDianaActual <= NUMDIANAS); redibujaPantalla(); scare_mouse(); textprintf(screen, font, 40,100, palette_color[2], "Partida terminada"); unscare_mouse(); readkey(); return 0; } /* Se concluye con la "macro" que pide Allegro */ END_OF_MAIN(); CONCLUSION Bueno esta prctica fue algo complicada puesto al uso de utilizar variables para no llegar a confundirnos en el momento de realizar las funciones, tambin se utilizan distintos rand como para el dimetro del plato y el de la parbola, entonces nos damos cuenta que las matemticas nos ayudan mucho, concidero que eso fue lo mas complicado ya que en lo dems fue solo usar un nuestra lgica y comprender lo que hacamos en cada bloque de instrucciones.