18. Mostrar y mover sólo el marciano. Octavo juego (aproximación "b"): Marciano 2 (*)
La idea de esta segunda aproximación es:
- Movimiento sólo del "marciano", de lado a lado, bajando en la pantalla y cambiando de forma. Se podrá interrumpir pulsando Esc. No deberá salirse por los lados, y si llega a la parte inferior deberá volver a la superior.
Debería resultar bastante fácil. La única novedad por ahora es eso de "cambiar de forma". Según el caso, nuestro "personaje" puede cambiar de apariencia cada vez que lo dibujamos, de forma sucesiva, o mantener una misma forma durante varios fotogramas. En este ejemplo, vamos a coger esta última opción, pero en su variante más sencilla: cada X fotogramas (y siempre los mismos, por ejemplo, cada 3) cambiaremos la apariencia del personaje y volveremos a empezar a contar.
Todo esto, en lenguaje mucho más cercano a los de programación sería:
cargar imagen 1 y 2 del marciano
entrar a modo gráfico
dibujar marciano en punto inicial
repetir
aumentar posicion horizontal
si se acerca a margen lateral de la pantalla
cambiar sentido horizontal de avance
bajar una línea en vertical
si se acerca a parte inferior de la pantalla
mover a parte superior
aumentar contador de "fotogramas"
si contador de fotogramas = numFotogramasPorImagen
cambiar apariencia de marciano
contador de fotogramas = 0
redibujar pantalla
pausa
hasta que se pulse ESC
Si se ha entendido la aproximación anterior, capaz de mostrar las imágenes, esta añade pocas novedades: calcular la nueva posición del marciano (cambiando de línea y de dirección o volviendo a la parte superior de la pantalla si corresponde) y salir sólo si se pulsa la tecla ESC, no con las demás teclas:
/*----------------------------*/ /* Intro a la programac de */ /* juegos, por Nacho Cabanes */ /* */ /* ipj18c.c */ /* */ /* Decimoquinto ejemplo: */ /* Movimiento de un */ /* marciano animado */ /* */ /* Comprobado con: */ /* - Djgpp 2.03 (gcc 3.2) */ /* y Allegro 4.02 - MsDos */ /*----------------------------*/ /* ------------------- Planteamiento de esta aproximación: cargar imagen 1 y 2 del marciano entrar a modo gráfico dibujar marciano en punto inicial repetir aumentar posicion horizontal si se acerca a margen lateral de la pantalla cambiar sentido horizontal de avance bajar una línea en vertical si se acerca a parte inferior de la pantalla mover a parte superior aumentar contador de "fotogramas" si contador de fotogramas = numFotogramasPorImagen cambiar apariencia de marciano contador de fotogramas = 0 redibujar pantalla pausa hasta que se pulse ESC ------------------- */ #include <allegro.h> /* -------------- Constantes globales ------------- */ #define ANCHOPANTALLA 320 #define ALTOPANTALLA 200 #define RETARDO 250 #define MARGENSUP 40 #define MARGENDCHO 30 #define MARGENIZQDO 30 #define MARGENINF 50 #define INCREMX 5 #define INCREMY 15 /* -------------- Variables globales -------------- */ PALETTE pal; BITMAP *imagen; BITMAP *nave; BITMAP *marciano1; BITMAP *marciano2; /* -------------- Rutina de inicialización -------- */ int inicializa() { allegro_init(); // Inicializamos Allegro install_keyboard(); install_timer(); // Intentamos entrar a modo grafico 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; } // e intentamos abrir imágenes imagen = load_pcx("spr_inv.pcx", pal); if (!imagen) { set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); allegro_message("No se ha podido abrir la imagen\n"); return 1; } set_palette(pal); // Ahora reservo espacio para los otros sprites nave = create_bitmap(16, 16); marciano1 = create_bitmap(16, 16); marciano2 = create_bitmap(16, 16); // Y los extraigo de la imagen "grande" blit(imagen, nave // bitmaps de origen y destino , 32, 32 // coordenadas de origen , 0, 0 // posición de destino , 16, 16); // anchura y altura blit(imagen, marciano1, 0, 32, 0, 0, 16, 16); blit(imagen, marciano2, 16, 32, 0, 0, 16, 16); // Y termino indicando que no ha habido errores return 0; } /* ------------------------------------------------ */ /* */ /* -------------- Cuerpo del programa ------------- */ int main() { int fotograma = 1; int xMarciano = MARGENIZQDO; int yMarciano = MARGENSUP; int desplMarciano = INCREMX; int salir = 0; // Intento inicializar if (inicializa() != 0) exit(1); do { // Parte que se repite hasta pulsar tecla clear_bitmap(screen); // Dibujo un marciano u otro, alternando if (fotograma==1) { draw_sprite(screen, marciano1, xMarciano, yMarciano); fotograma = 2; } else { draw_sprite(screen, marciano2, xMarciano, yMarciano); fotograma = 1; } // Y espero un poco rest(RETARDO); // Finalmente, calculo nueva posición xMarciano += desplMarciano; // Compruebo si debe bajar if ((xMarciano > ANCHOPANTALLA-16-MARGENDCHO) || (xMarciano < MARGENIZQDO)) { desplMarciano = -desplMarciano; // Dirección contraria yMarciano += INCREMY; // Y bajo una línea } // O si debe volver arriba if (yMarciano > ALTOPANTALLA-16-MARGENINF) { xMarciano = MARGENIZQDO; yMarciano = MARGENSUP; desplMarciano = INCREMX; } if (keypressed()) if (readkey() >> 8 == KEY_ESC) salir = 1; } while (!salir); destroy_bitmap(imagen); readkey(); return 0; } /* Termino con la "macro" que me pide Allegro */ END_OF_MAIN();
Si está todo entendido, vamos ahora a mover dos cosas a velocidad distinta (el "marciano" y nuestra nave)...