Esta es solamente una disculpa para mejorar un poco el código sobre el
scroll, así como una ampliación donde introducimos los círculos arcoiris de
allegro.
También sirve para ilustrar la manera en cómo se utiliza la estructura
scroll.
Un saludo a toda la lista.
JFHorizon
/*------------------------------------------------------------
Círculos arcoiris interactivos con scroll y cámara
en el ratón.
JFHorizon <jfhorizon@...>
John Alexis Guerra Gómez <aguerra@...>
------------------------------------------------------------*/
#include <string.h>
#include <stdio.h>
#define ALLEGRO_STATICLINK
#include<allegro.h>
#define RANDOM(n) (((float)rand() / (float)RAND_MAX)*(n))
#define W 640
#define H 480
BITMAP *buffer_screen;
BITMAP *buffer_escena;
typedef struct scroll_
{
int x0; // Coordenadas del primer plano
int y0;
}SCROLL_T;
SCROLL_T *scroll;
void reserve_memory_scroll(int num_scrolles)
{
if ((scroll = (SCROLL_T *) malloc(num_scrolles * sizeof(SCROLL_T) ))==
NULL)
{
allegro_message("Falla la alocacion de memoria \n%s\n",
allegro_error);
exit(4);
}
// Inicializa la estructura de scroll.
memset(scroll, 0, num_scrolles * sizeof(SCROLL_T));
}
// -------------------------------------------------------------------------
// Mueve el scroll por software
// -------------------------------------------------------------------------
void Scroll(int num_scroll, BITMAP *escenario_entra, int new_x0, int new_y0,
int new_camera)
{
if (new_camera==0) // Camara en vision general (al mouse)
{
if (new_x0>=0 && new_y0>=0 && new_x0<=(128+escenario_entra->w/2)
&& new_y0<=escenario_entra->h/2)
{
scroll[num_scroll].x0= new_x0; // region
01
scroll[num_scroll].y0= new_y0;
}
if (new_x0>=(128+escenario_entra->w/2) && new_y0>=0
&& new_x0<=(128+escenario_entra->w) &&
new_y0<=escenario_entra->h/2)
{
scroll[num_scroll].x0=128+escenario_entra->w/2; // region
02
scroll[num_scroll].y0=new_y0;
}
if (new_x0>=0 && new_y0>=escenario_entra->h/2 &&
new_x0<=(128+escenario_entra->w/2)
&& new_y0<=escenario_entra->h)
{
scroll[num_scroll].x0=new_x0; // region
03
scroll[num_scroll].y0=escenario_entra->h/2;
}
if (new_x0>=(128+escenario_entra->w/2) &&
new_y0>=escenario_entra->h/2
&& new_x0<=escenario_entra->w && new_y0<=escenario_entra->h)
{
scroll[num_scroll].x0=128+escenario_entra->w/2; // region
04
scroll[num_scroll].y0=escenario_entra->h/2;
}
if (new_x0>=0 && new_y0<0 && new_x0<=(128+escenario_entra->w/2))
{
scroll[num_scroll].x0=new_x0; // region
05
scroll[num_scroll].y0=0;
}
if (new_x0>=(128+escenario_entra->w/2) && new_y0<=0 &&
new_x0<=escenario_entra->w)
{
scroll[num_scroll].x0=128+escenario_entra->w/2; // region
06
scroll[num_scroll].y0=0;
}
if (new_x0>=escenario_entra->w && new_y0<=escenario_entra->h/2)
{
scroll[num_scroll].x0=128+escenario_entra->w/2; // region
07
scroll[num_scroll].y0=0;
}
if (new_x0>=escenario_entra->w && new_y0>=escenario_entra->h/2
&& new_y0<=escenario_entra->h)
{
scroll[num_scroll].x0=128+escenario_entra->w/2; // region
08
scroll[num_scroll].y0=escenario_entra->h/2;
}
if (new_x0>=(128+escenario_entra->w/2) && new_x0<=escenario_entra->w
&& new_y0>=escenario_entra->h)
{
scroll[num_scroll].x0=128+escenario_entra->w/2; // region
09
scroll[num_scroll].y0=escenario_entra->h/2;
}
if (new_x0>=0 && new_x0<=(128+escenario_entra->w/2) &&
new_y0>=escenario_entra->h)
{
scroll[num_scroll].x0=0; // region
10
scroll[num_scroll].y0=escenario_entra->h/2;
}
if (new_x0<=0 && new_y0>=0 && new_y0<=escenario_entra->h/2)
{
scroll[num_scroll].x0=0; // region
11
scroll[num_scroll].y0=new_y0;
}
if (new_x0<=0 && new_y0>=escenario_entra->h/2 &&
new_y0<=escenario_entra->h)
{
scroll[num_scroll].x0=0; // region
12
scroll[num_scroll].y0=escenario_entra->h/2;
}
if (new_x0<=0 && new_y0<=0)
{
scroll[num_scroll].x0=0; // region
13
scroll[num_scroll].y0=0;
}
if (new_x0>escenario_entra->w && new_y0<=0)
{
scroll[num_scroll].x0=escenario_entra->w/2; // region
14
scroll[num_scroll].y0=0;
}
if (new_x0>escenario_entra->w && new_y0>escenario_entra->h)
{
scroll[num_scroll].x0=128+escenario_entra->w/2; // region
15
scroll[num_scroll].y0=escenario_entra->h/2;
}
if (new_x0<=0 && new_y0>escenario_entra->h)
{
scroll[num_scroll].x0=0; // region
16
scroll[num_scroll].y0=escenario_entra->h/2;
}
// 640-128, 480
}
// Refrescar la escena.
blit(escenario_entra, buffer_screen, scroll[0].x0, scroll[0].y0, 0, 0,
W, H);
}
int main()
{
PALETTE palette;
RGB temp;
register int c;
static int antes_left=0;
int i;
register int velx=0, vely=0;
register int x, y;
if(install_allegro(SYSTEM_AUTODETECT, &errno, atexit))
{
allegro_message(" Error inicializando el sistema \n%s\n",
allegro_error);
allegro_exit();
}
install_timer();
if(install_keyboard())
{
allegro_message(" Error inicializando teclado de Allegro \n%s\n",
allegro_error);
allegro_exit();
return(-1);
}
if(install_mouse()<0)
{
allegro_message(" Error inicializando el controlador del raton de
Allegro \n%s\n", allegro_error);
allegro_exit();
return(-1);
}
if(set_gfx_mode(GFX_AUTODETECT_WINDOWED, W, H, W, H)<0)
{
allegro_message("Modo grafico no detectado \n%s\n",
allegro_error);
allegro_exit();
}
/* first set the palette to black to hide what we are doing */
set_palette(black_palette);
/* fill our palette with a gradually altering sequence of colors */
for (c=0; c<64; c++) {
palette[c].r = c;
palette[c].g = 0;
palette[c].b = 0;
}
for (c=64; c<128; c++) {
palette[c].r = 127-c;
palette[c].g = c-64;
palette[c].b = 0;
}
for (c=128; c<192; c++) {
palette[c].r = 0;
palette[c].g = 191-c;
palette[c].b = c-128;
}
for (c=192; c<256; c++) {
palette[c].r = 0;
palette[c].g = 0;
palette[c].b = 255-c;
}
// Inicializa scroll
reserve_memory_scroll(1);
// Creamos bitmap para la pantalla
buffer_screen=create_bitmap(SCREEN_W, SCREEN_H);
if(!buffer_screen)
{
allegro_message("Disculpa, no hay memoria disponible \n%s\n",
allegro_error);
allegro_exit();
}
// Creamos bitmap para la escena
buffer_escena=create_bitmap(1600, 1200);
if(!buffer_escena)
{
allegro_message("Disculpa, no hay memoria disponible para la
escena \n%s\n", allegro_error);
allegro_exit();
}
// pintamos la escena
for(i=0; i<=100; i++)
{
vline(buffer_escena, i*16, 0, 1200, i);
hline(buffer_escena, 0 ,i*12, 1600, i);
}
// nos colocamos en la escena en este caso en el mismo centro.
scroll[0].x0= 1600/2-SCREEN_W/2;
scroll[0].y0= 1200/2-SCREEN_H/2;
while(!key[KEY_ESC])
{
x= mouse_x+scroll[0].x0;
y= mouse_y+scroll[0].y0;
if (mouse_x<= 20 && velx>-16) { velx-=4; }
if (mouse_x>=(W-20) && velx< 16) { velx+=4; }
if (mouse_y<= 20 && vely>-16) { vely-=4; }
if (mouse_y>=(H-20) && vely< 16) { vely+=4; }
scroll[0].x0= scroll[0].x0+velx;
scroll[0].y0= scroll[0].y0+vely;
Scroll(0, buffer_escena, scroll[0].x0, scroll[0].y0, 0);
if (velx>0) {velx-=2; }
if (vely>0) {vely-=2; }
if (velx<0) {velx+=2; }
if (vely<0) {vely+=2; }
// apretando la [C] limpia la escena
if(key[KEY_C]) {
show_mouse(NULL);
clear(buffer_escena);
// repintamos la escena
for(i=0; i<=100; i++) {
vline(buffer_escena, i*16, 0, 1200, i);
hline(buffer_escena, 0 ,i*12, 1600, i);
}
}
// apretando la [k] genera circulos arcoiris al azar en la
escena
if(key[KEY_K]) {
int x_scena= RANDOM(buffer_escena->w);
int y_scena= RANDOM(buffer_escena->h);
show_mouse(NULL);
for(c=(30+RANDOM(H/2-30)); c>0; c--)
circlefill(buffer_escena, x_scena, y_scena, c, c);
}
// genera un circulo arcoiris en la posicion del raton.
if((mouse_b &1) && !antes_left) {
show_mouse(NULL);
for(c=(30+RANDOM(H/3-30)); c>0; c--)
circlefill(buffer_escena, mouse_x+scroll[0].x0,
mouse_y+scroll[0].y0, c, c);
}
antes_left=(mouse_b &1);
temp = palette[255];
for(c=255; c>0; c--)
palette[c] = palette[c-1];
palette[0] = temp;
set_palette(palette);
show_mouse(buffer_screen);
blit(buffer_screen, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
show_mouse(NULL);
clear(buffer_screen);
}
destroy_bitmap(buffer_screen);
destroy_bitmap(buffer_escena);
free(scroll);
allegro_exit();
return 0;
}
END_OF_MAIN();