Programación Específica > Allegro

 Necesito Una Ayudita Sobre Colisiones

(1/2) > >>

turko666:
Antes que nada buenasss a todos  :rolleyes:
tengo un problemaa con el tema de colisiones, paso a poner el codigo y despues explico  en que cosas tengo dudas:


--- Citar ---#include <allegro.h>
#include <stdlib.h>

#define TILESIZE      32
#define TILES_ANCHO   32
#define TILES_ALTO    24

BITMAP *buffer;
BITMAP *grid;
BITMAP *player;
BITMAP *tiles;

#define UP       0
#define DOWN     1
#define LEFT     2
#define RIGHT    3

//variables del personaje
int px, py, dir, frame,aguaframe;

char posx[5],posy[5];

short mapa[24][32] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }};

//prototipo funciones
void inicia_todo();
void borra_todo();
void dibuja_mapa();
void mover(int d);
void dibuja_player();
void dibuja_todo();
void blitbuffer( BITMAP *bmp );

// ------------------------- estructura de funciones -------------------------------
void inicia_todo()
{
     allegro_init();
     install_keyboard();
     install_timer();
     install_mouse();
     set_color_depth( 16 );
     set_gfx_mode( GFX_AUTODETECT, 1024, 768, 0, 0);
     
     buffer=create_bitmap(SCREEN_W,SCREEN_H);
     clear(buffer);
     
     grid=create_bitmap(TILES_ANCHO * TILESIZE, TILES_ALTO * TILESIZE);
     
     player=load_bitmap("player.pcx",NULL);
     tiles=load_bitmap("tilemaps.pcx",NULL);
     
     px=32;
     py=32;
     dir=DOWN;
     frame=0;
}

// ---------------------------------------------------------------------
void borra_todo()
{
    if ( buffer )
        destroy_bitmap( buffer );

    if ( grid )
        destroy_bitmap( grid );
}

// -----------------------------------------------------------------------
void dibuja_player()
{
    textout(buffer,font,"3",px,py,-500);
}
// -----------------------------------------------------------------------
void dibuja_mapa()
{
  int i , j , x=0 , y=0;
       for(i=0;i<24;i++)
             {
                for(j=0;j<32;j++)
                      {
                      switch(mapa[j])
                            {
                            case 0: textout(grid,font,"0",j*TILESIZE,i*TILESIZE,255);break;
                            case 1: textout(grid,font,"1",j*TILESIZE,i*TILESIZE,5000);break;
                            case 2: blit(tiles,grid,x,0 * TILESIZE ,i * TILESIZE, j * TILESIZE, TILESIZE, TILESIZE);break;
                            }
                      }
             }
  blit( grid, buffer, 0, 0, 0, 0, TILES_ANCHO * TILESIZE, TILES_ALTO * TILESIZE );               
}
// -----------------------------------------------------------------------
void dibuja_todo()
{
     dibuja_mapa();
     dibuja_player();
     blitbuffer(buffer);
}
// ------------------------------------------------------------------------
void blitbuffer( BITMAP *bmp )
{
    acquire_screen();
    blit( bmp, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H );
    release_screen();
}       

// ------------------------------------------------------------------------
void inc_frame(int d)
{
   if (dir==UP)
   {   
  frame++;
  if (frame>1) frame=0;
   }
   if (dir==DOWN)
   {
  frame++;
  if (frame<4 || frame>5) frame=4;
   }
   if (dir==LEFT)
   {
  frame++;
  if (frame<6 || frame>7) frame=6;
   }
   if (dir==RIGHT)
   {
  frame++;
  if (frame<2 || frame>3) frame=2;
   }
}
// --------------------------------------------------------------
void mover(int d)
{
    int px_rel=px/TILESIZE;
    int py_rel=py/TILESIZE;
    dir=d;
   inc_frame(dir);
   switch(dir)
    {
    case LEFT:  if(mapa[py_rel][px_rel-1]!=0)px-=TILESIZE;break;
    case RIGHT: if(mapa[py_rel][px_rel+1]!=0)px+=TILESIZE;break;
   case UP:    if(mapa[py_rel-1][px_rel]!=0)py-=TILESIZE;break;
   case DOWN:  if(mapa[py_rel+1][px_rel]!=0)py+=TILESIZE;break;
    }
}

// ---------------------- MAIN ------------------------------------
int main()
{
    bool done = false;
    inicia_todo();

    while ( !done )
    {
        dibuja_todo();
        rest(50);

// ESC para salir

        if (key[ KEY_ESC ] ) done = true;
       
        if (key[ KEY_DOWN ] ) mover(DOWN);
        if (key[ KEY_UP ] ) mover(UP);
        if (key[ KEY_LEFT ] ) mover(LEFT);
        if (key[ KEY_RIGHT ] ) mover(RIGHT);
    }
    borra_todo();
    return 0;
}
END_OF_MAIN();

--- Fin de la cita ---

Bueno el programa en si anda, remplace los graficos por ceros y unos y un 3 para el personaje... esta basado basicamente en una matriz de ceros y unos  (0 para los tiles no caminables, 1 para los caminables)

El problema viene en la funcion mover(int d) porque el personaje se mueve de 32px a 32px y eso le quita mucha "delicadesa" al juego, es como si fuese a los saltos, lo que quiero hacer es que las cordenadas del personaje X e Y disminuyan o aumenten (depende la orden) en 8px en vez de 32 (TILESIZE), pero cuando cambio estos valores fallan las colisiones... si prueban el programa van a ver que de izq. a derecha y de arriba hacia abajo las colisiones andan perfecto pero cuando uno camina de derecha a izq. colisiona mucho antes de que choque con un 0... lo mismo de abajo hacia arriba.


--- Citar ---    case LEFT:     if(mapa[py_rel][px_rel-1]!=0)px-=8;break;
    case RIGHT:  if(mapa[py_rel][px_rel+1]!=0)px+=8;break;
    case UP:       if(mapa[py_rel-1][px_rel]!=0)py-=8;break;
    case DOWN:  if(mapa[py_rel+1][px_rel]!=0)py+=8;break;


--- Fin de la cita ---

es solo eso, si algun entendido me puede dar una mano se agradece  :D

Geo:
El problema es que, cuando vas hacia arriba o hacia la izquierda, la división que haces al inicio para obtener las "coordenadas relativas", no te permite moverte pues cualquier valor menor a 32 antes de llegar a la penúltima casilla, se tomará como si estuvieras en la última (espero haberme explicado bien :P).

Prueba con esto:

--- Código: Text ---   switch ( dir ) {    case LEFT:      if ( mapa[ py_rel ][ px_rel - 1 ] != 0 || ( px % TILESIZE != 0 ) ) {        px -= 8;      }      break;    case RIGHT: if(mapa[py_rel][px_rel+1]!=0)px+=8;break;    case UP:      if ( mapa[ py_rel -1 ][ px_rel ] != 0 || ( py % TILESIZE != 0 ) )        py -= 8;            break;    case DOWN: if(mapa[py_rel+1][px_rel]!=0)py+=8;break;  }  
Saludos,
José Jorge (Geo).

turko666:
:D (no estaba tan equivocado) es lo mismo que me plantie yo, habia intentado hacer una condicion sacando el resto... pero yo habia intentado if(px%TILESIZE==0) y ahi fue donde meti la pata. tiene que ser distinto de 0, no igual  :unsure:

Muchas gracias por darme una mano... prometo mas adelante cuando lleve un poquito mejor el juego lo posteo. En este momento me estoy metiendo a la parte mas dificil que es controlar el personaje mediante el mouse calculando phatfinding y todo eso que me resulta bastante engorroso  :comp: y luego tengo que pasar al scrolling de pantalla.

En fin gracias de nuevo!!

Geo:
Estaré atento para cuando nos muestres algo, suerte y ¡ánimo!

Saludos,
José Jorge (Geo).

turko666:
Mmm hay algo que le falla todavia a las colisiones, voy a poner un screenshot para que te des una idea mas clara (no se como se adjuntan pero voy a intentar)

Bueno en el dibujo las lineas fuccias serian los limites de cada celda de la matriz no caminable... el personaje (3) nunca podria estar 8 px mas arriba ni mas atras que un 0... deberia estar 32 px como minimo porque al utilizar tiles de 32px al ver el resultado ya usando tiles graficos el personaje se mete en el agua por ejemplo  :rain:

Navegación

[0] Índice de Mensajes

[#] Página Siguiente

Ir a la versión completa