problema vectores, allegro.

Iniciado por MasterPunk, 4 Enero 2012, 16:11 PM

0 Miembros y 1 Visitante están viendo este tema.

Kherom

#10
Cita de: MasterPunk en  9 Enero 2012, 01:19 AM
Tienes razon, mejor trabajar con vectores que con 2 variables.
Sobre tu planteamiento...
El vector unitario tiene de modulo 1, por tanto el desplazamiento en x y en y va a ser menor de uno por cada frame, y no puedo desplazarme medios pixeles. Al pasarlo a int va a ser siempre 0. (si no me equivoco).

Él te dice que saques el vector unitario y luego lo multipliques por la velocidad que desees. Por otro lado un entero se redondea siempre a 0, pero si mantienes las variables de la posición como float los pequeños incrementos se irán acumulando y avanzará el píxel en cuanto llegue. Así que deberías trabajar siempre con floats y hacer el cast en el momento de dibujar.

En cualquier caso yo haría algo así (Puede que haya errores, ahora no puedo probar, sólo tengo el bloc de notas xD):

float tan, ang, vx, vy, velocidad; //Deberias pasar todo a floats


if (posx==derx && posy==dery) // Ponemos la velocidad a 0 cuando alcanzamos la posicion (Creo que seria conveniente hacer algo como if( posx>(derx-0.001)&&posx<(derx+0.001) && posy>(dery-0.001)&&posy<(dery+0.001) )por la posible imprecision que tienen los float
{
vx=0;
vy=0;
}
else
{
if (derx-posx==0) //Si no hay x la velocidad esta en y
{
vx=0;
if(dery-posy>0) //Si esta por encima
vy=velocidad;
else
VY=-velocidad;
}
else
{
tan= (dery-posy)/(derx-posx) //No te olvides de los parentesis
ang=(float)atan((double)tan);//Según cómo lo hagas deberías tener en cuenta si la velocidad es positiva o negativa, no me apetece poner los if ahora xD
vy = (sin(angulo)*velocidad);
vx = (cos(angulo)*velocidad); //creo que los cast son automaticos, si no los pones, también se podrian quitar en la atan ya que creo que sale sólo un warning, pero no estoy seguro (no lo puedo comprobar ahora)
}
}

//Todo lo anterior debería ejecutarse sólo una vez al hacer clik, luego sólo tendrías que comprobar si ya ha llegado al final para poner la velocidad a 0.

posy+=vy;
posx+=vx;


La opción del vector unitario también está bien pero pierdes la opción de mover el personaje con las teclas al no tener la dirección, con éste método le das un ángulo en radianes y se va moviendo.

En cuanto a lo de que no se mueva demasiado rápido lo que tienes que hacer es 1º jugar con el valor que le das a la velocidad y sobre todo tener en cuenta que el framerrate puede variar sobre según el equipo, así que deberías calcular los ms entre frame y frame para adaptarla.

Algo tipo


posy+=vy*msTranscurridos;
posx+=vx*msTranscurridos;


Siendo msTrancurridos el tiempo que ha pasado desde el último frame. Otra opción es dejar el framerrate fijo (haciendo que el código sólo se ejecute cada x milisegundos) y olvidar ésto, pero en equipos lentos además de reducir el framerate se reducirá la velocidad.

MasterPunk

Algo parecido habia intentado yo, pero hay un problemilla:

posx y posy deben ser enteros para poder mostrar el grafico del personaje:

Código (c++) [Seleccionar]
void putpixel(BITMAP *bmp, int x, int y, int color); //si, dibujo al personaje en pantalla pixel a pixel...  :rolleyes:

El codigo que has puesto seria perfecto si la pantalla fuera mas grande, pero siendo como es la velocidad perfecta es de 0,1 o 0,2 pixeles por frame.

Código (cpp) [Seleccionar]
float velocidad = 0.2;
posx += (int)velocidad;


El personaje no se mueve. Por ello he utilizado el contador, para movel el personaje cada v frames, siendo v la velocidad.

Por lo demas todo perfecto, voy a arreglar y a probar el codigo. Gracias.

Kherom

#12
A ver:

float posxf=0;

posxf+=0.2;
putpixel(BITMAP *bmp, posf, int y, int color);

No hace nada.

posxf+=0.2;
putpixel(BITMAP *bmp, posf, int y, int color);

No hace nada.

posxf+=0.2;
putpixel(BITMAP *bmp, posf, int y, int color);

No hace nada.

posxf+=0.2;
putpixel(BITMAP *bmp, posf, int y, int color);
No hace nada.

posxf+=0.2;
putpixel(BITMAP *bmp, posf, int y, int color);

Avanza un píxel (posf ahora con el cast vale 1, antes 0).

Así es como lo tienes que hacer, vas sumando la posición al float y luego se lo pasas a la función que lo dibuje como entero, los decimales se desprecian pero cada x frames avanza un píxel. De ese modo no te tienes que preocupar por qué valores das a la velocidad, ya se moverá cuando se tenga que mover.

Al pasarle el float a la función, que acepta enteros, hará automáticamente un cast, asi que no te tienes que preocupar. Si quieres evitar el warning haz el cast a mano al pasar el argumento ( (int)posxf );

MasterPunk



Muahahaha, 200 warnings pero funciona =D
Que alegria, asi debia sentirse dios cuando le dijeron como compilar el mundo xD

Que funcione es lo de menos, lo importante es que en este post me habeis enseñado varias cosas que tenia que saber.
Muchas gracias por la ayuda ;)

Kherom

#14
Si haces el cast a int a mano función( (int)numeroflotante ) evitarás los warnings, ya que para lo único que sirven en éste caso es para indicar una posible pérdida de precisión, que es justamente lo que andas buscando.

De todas formas ahora que me fijo, para que tengas tantos warnings, ¿Llamas a la función una vez por píxel A MANO? xD

MasterPunk

Cita de: Kherom en 11 Enero 2012, 01:07 AM
Si haces el cast a int a mano función( (int)numeroflotante ) evitarás los warnings, ya que para lo único que sirven en éste caso es para indicar una posible pérdida de precisión, que es justamente lo que andas buscando.

De todas formas ahora que me fijo, para que tengas tantos warnings, ¿Llamas a la función una vez por píxel A MANO? xD

Si, lo e los warnings ya lo he arreglado, que para eso esta la herramienta remplazar :P

Es una p***da que en allegro 4 no se puedan meter png, y como con las bmp se ve el cuadradito negro alrededor de la imagen lo he arreglado dibujandolo pixel a pixel. Costoso, pero ya esta hecho xD
40x40 pixeles en color.

Si no conoces el camino rapido te toca andar el largo =S

Kherom

Eliges un color para las transparencias (por ejemplo un rosa que no te guste, o el negro si las imágenes no tienen negro), luego cargas en memoria la imagen y mediante un bucle for pintas sólo los píxeles que no sean de ese color.

MasterPunk

no se ni como comprobar el color de los pixeles ni como pintar solo algunos pixeles, asi que si me dices como me harias un segundo gran favor

Kherom

#18
Cita de: MasterPunk en 12 Enero 2012, 00:49 AM
no se ni como comprobar el color de los pixeles ni como pintar solo algunos pixeles, asi que si me dices como me harias un segundo gran favor

Primero necesitas los datos de la imagen cargados en memoria, luego compruebas con un editor de imágenes cuál es el valor del color que vayas a usar para la transparencia, y luego mediante un par de bucles for vas pintando sólo los que no coincidan con ése color.

MasterPunk

#19
voy a volver a leer en el manual de allegro los objetos bitmap