PDA

Ver la versión completa : Colision en los mapas de tiles



Eskema
15/12/2005, 21:34
Muy buenas tras un tiempo haciendo pruebas y en vista de q no me aclaro, vengo a daros la brasa un poco xD.
No consigo hacer la colision entre el personaje y los tiles del mapa de fondo.

Tengo una imagen alargada con los tiles, 100 en mi caso de 16x16, bien hago el mapa con el mappy, lo exporto a .h y obtengo un array numerico, es decir tengo los numeros de los tiles correspondientes a cada trozo de tile.
Perfecto hasta aqui, cargo el mapa, hago el scroll, muevo al personaje, ¿y como detecto la colision con el numero de tile q yo quiero?
Estaba probando con algo como esto, pero no consigo q vaya

int Colision_Tile(tObjeto *obj)
{

int tile_x,tile_y,tile_num;

tile_x = obj->x+obj->ancho-2;
tile_y = obj->y+24;
tile_num = mapa_del_nivel[tile_y][tile_x];


if (tile_num == '50' || '51') // si es el numero 50 y 51 es pared
return 1;
else
return 0;
}

Luego pongo para comprobar si se puede mover
if((Colision_Tile(tJugador))==1)
{
Movimiento(tJugador.x+0, tJugador.y-0, &tJugador);
}


Pero no consigo nada mas q la aplicacion se cierre, ¿arguna halludita paaaayo xDD?

Gammenon
15/12/2005, 21:45
Comprueba que al indexar no te excedas de los límites de la matriz donde guardas los tiles.
Aparte de esto, la condición


if (tile_num == '50' || '51')

no creo que esté bién. Creo que tendría que ser algo así como


if(tile_num == 50 || tile_num == 51)


Bueno, a ver si te sirve de ayuda ;)

Petiso
15/12/2005, 21:47
Hola !

Que yo sepa, en C no se puede hacer:
if (tile_num == '50' || '51')

Has de hacer:
if (tile_num == '50' || tile_num == '51')

Y luego no entiendo esta linea:
Movimiento(tJugador.x+0, tJugador.y-0, &tJugador);

Por que le sumas 0 ??????

Bye !

EDIT: se me han adelantado :-p
EDIT2: No entiendo otras cosas ... tendries de explciar que es cada variable....

Eskema
15/12/2005, 21:59
Pues le sumo 0, pq movimiento es para hacer la animacion del personaje sin moverse, por eso sumo 0, lo mantengo animado pero no lo muevo.

Bueno el caso es q sigo sin saber detectar en q numero de tile esta el personaje y actuar en consecuencia.


Edito, las variables, tObjeto es un struct donde creo al personaje, tipico vamos. int todo, x,y,velocidad,vidas,etc. Y mapa_del_nivel es el array donde esta almacenado el mapa de tiles q exporta el mappy

Petiso
15/12/2005, 22:02
Pues para sumarle 0, no le sumes nada :-p


Objeto.x i objeto.y, son cordenadas de pantalla, o cordenadas del mapa de titles ?

Bye !

Eskema
15/12/2005, 22:06
Coordenadas de pantalla

Petiso
15/12/2005, 22:08
Entonces tienes que hacer algo asi:

tile_x = (obj->x-INC_X)/obj->ancho;
tile_y = (obj->y-INC_Y)/obj->ancho;

INC_X i INC_Y es por si el mapa de titles no empieza en las cordenadas 0,0.

Bye !

EDIT: Suponiendo que obj->ancho, es el ancho del title.

Eskema
15/12/2005, 22:12
INC_X q representaria? ¿el obj tile?. Cuando hago

int tile_x,tile_y,tile_num;

tile_x = obj->x+obj->ancho-2;
tile_y = obj->y+24;
tile_num = mapa_del_nivel[tile_y][tile_x];

Lo q trato de hacer es: si obj->x y obj->y (q apunta al personaje) estan en el tile_num = 50, entonces quiero hacer colision. Obj.x e obj.y se refieren como dices a las coordenadas del personaje en pantalla. Supongo q haciendo eso, miro si x e y corresponden al numero de tile del array q busco ¿no?

Petiso
15/12/2005, 22:19
Me epxlico mejor:


+------------
|
| Y
| o-----
| X |


+= (0,0) de pa pantalla
o= Inicio del mapa de titles.

(INC_X,INC_Y) son las cordenadas de o.
Si el mapa de titles empieza a (0,0), oblidate de todo :-p

Luego, supongo que obj.x i obj.y, son las cordenadas del CENTRO del personaje ....
Por lo tanto mejoro lo que he dicho antes:

tile_x = (obj->x-INC_X)/title_ancho;
tile_y = (obj->y-INC_Y)/title_alto;

Esta mas claro ?

Bye !

Eskema
15/12/2005, 22:22
El mapa comienza en 0,0 ademas x, y NO son el centro del personaje, supongo q al querer comprobar una punta en vez del centro hace no encuentre el numero q busco en el array

Petiso
15/12/2005, 22:23
Okis, entonces:
- Elimina INC_X e INC_Y .... :-p

- Que punto de personaje son x e y ??? Quadro superior derecho ??

Bye !

PD: Si queires msn: cvagcvagARROBAhotmail.com

Eskema
15/12/2005, 22:24
Bueno modifico y cambio a

tile_x = obj->x+obj->ancho/2;
tile_y = obj->y+obj->alto/2;

De esta forma supongo q SI tengo el centro ¿no?

Petiso
15/12/2005, 22:26
Exacto, con esto tienes el centro ..... ahora solo te falta dividir por el ancho o alto del title para saber a que title se enquentra.

Bye !

Eskema
16/12/2005, 03:19
Gracias Petiso por tu ayuda, ahora puedo seguir enganchandome en otras cosas :)

Petiso
16/12/2005, 03:53
Son 10.000 :-p

Adeu !

Damizean
16/12/2005, 04:57
Si quieres transformar las coordenadas del mundo a la del mapa, si es un mapa hecho con tiles de 16x16, solo tienes que dividir la posicion entre 16 (o desplazarlo a la derecha 4 bits)

int mapCollision ( int x, int y )
{
int xMap = x >> 4; // x / 16
int yMap = y >> 4; // y / 16
int mapTile = 0;

if ( xMap < 0 || yMap < 0 || xMap >= map_width || yMap >= map_height )
{
mapTile = map[yMap][xMap];
if ( mapTile == 50 || mapTile == 51 ) return 1;
else return 0;
} else return 0;
}

Asi solo tendrás que comprobar "if ( mapCollision(obj_x + ancho, obj_y)) tal tal".

saucjedi
16/12/2005, 16:57
Que yo sepa, en C no se puede hacer:
if (tile_num == '50' || '51')


Poderse se puede, y ahi radica un problema bastante grave. Al ser un OR el if dara verdadero si uno de los dos se cumplen. En C si una expresion da 0 se considera falsa, y si da distinto de cero (sea cual sea el valor) es verdadera.

Siguiendo la logica del if, tenemos que la expresion 'tile_num == '50'' al ser una comparacion solo puede tener dos resultados, 0 o 1 (C asigna estos valores a las operaciones logicas siguiendo la regla que he expuesto antes, solo que en este caso en lugar de asignar un numero cualquiera a verdadero, asigna un 1 para hacer la cosa mas comprensible).

Sin embargo, la expresion '51' tiene solo un unico resultado: ¡51! y como 51 SIEMPRE es mayor que cero, esa expresion SIEMPRE da verdadero, con lo que el if en conjunto da verdadero sea cual sea el valor de tile_num.

Se que es un rollazo lo que he soltado, pero ojo con eso porque es una de las 'trampas' de C

Petiso
16/12/2005, 17:30
Al decir que "no se puede hacer", queria decir que no hace lo que eskema pensava que hacia.

Esta claro que en C se puede hacer todo :-p

saucjedi
16/12/2005, 23:41
Al decir que "no se puede hacer", queria decir que no hace lo que eskema pensava que hacia.


Ya lo imaginaba, pero vista la naturaleza del error, he puesto toda la explicacion. Todos creo que hemos pasado por ahi (al menos yo si) y mejor excederme explicandolo que quedarme corto :)

Damizean
17/12/2005, 01:09
De hecho '51' no se como no te da error, ¡es una cadena! (o al menos, un caracter).

if ( Noseque == 51 || Noseque == 52 ) asi es como se tiene que hacer si quieres comparar numeros

saucjedi
17/12/2005, 03:12
De hecho '51' no se como no te da error, ¡es una cadena! (o al menos, un caracter)

Hasta donde yo se, a C eso le da completamente igual :shock: Deja en manos del programador el saber lo que se esta haciendo. Para el compilador no es mas que una expresion, el la evalua y obtiene un codigo numerico y ya esta. Creo que hay algunos compiladores (me viene a la cabeza Watcom, aunque no lo se seguro) que toman esto como un error, pero vamos, que en sintaxis es correcto.

Eskema
17/12/2005, 03:34
Buenos consejos, a ver si en el futuro no meto la pata en cosas asi, por lo menos ya tengo las colisiones funcionando de maravilla gracias a las explicaciones claras de Petiso :)

Damizean
17/12/2005, 17:46
No, porque las cadenas son punteros a una secuencia de unsigned char que supuestamente deberia acabar en 0, no puede ser evaluado a la hora de comparar con un entero (como mucho podrias comparar punteros, o el contenido de la propia cadena de alguna otra forma).

Lo unico que se puede evaluar junto a un entero es un caracter (letra ascii que va entre '), por ejemplo

if ( variable == 'A' ) // La variable es igual al valor ASCII que corresponderia a A (65 creo recordar)