Foros - Stratos

Programadores => General Programadores => Mensaje iniciado por: Abc7 en 30 de Julio de 2004, 10:22:58 PM

Título: [vb6] Caminar En Diagonal?
Publicado por: Abc7 en 30 de Julio de 2004, 10:22:58 PM
 Bueno si... este es mi primer mensaje  :D  asi que primero me presento, soy Jorge de Argentina =D
bueno el problema que tengo esss.. que no puedo hacer caminar en diagonal al tipito :( porq si pongo q cuando presione arriba y derecha por ejemplo, que se mueva para arriba y para la derecha.. si se estaba moviendo para arriba va a hacer una especie de turbo :S
quisiera saber si por algun lado hay algun buen manual o tutorial de como haceeer que se mueva en diagonal usando vb6 y SIN usar un tile engine isometrico

si no me exprese bien entonces diganme que adjunto mi codigo

saludos y gracias  (ole)  (ole)  (ole)  
Título: [vb6] Caminar En Diagonal?
Publicado por: [EX3] en 31 de Julio de 2004, 04:15:14 AM
 Mmm, esto me suena... si eres kien yo creo ke eres bienvenido al foro, y si no tb, por supuesto  :D

Amos a ver, supon ke tu personaje usa dos coordenadas para la posicion, es lo mas normal, vamos, coordenada X ke indica su posicion lateral (derecha e izquierda) y coordenada Y, ke indica su altura en pantalla (Arriba y abajo).

Algo basico, cuando tu personaje se mueve hacia la derecha lo ke hace es incrementar su posicion X (X = X + 1 por ejemplo) y cuando se mueve a la izquierda lo contrario (X = X - 1) y cuando se mueve hacia abajo incrementa Y (Y = Y + 1) y al subir lo contrario (Y = Y - 1). Pues bien, si lo ke kieres es ke se mueva en diagonal, hacia la derecha y abajo, por ejemplo, seria (X = X + 1, Y = Y + 1). En principio no tendria ke hacer ningun efecto de aceleracion ni nada por el estilo.

Si puedes postear algo del codigo para ver ke es lo ke te produce el aceleron seguramente podamos ayudarte algo mas. Seguramente el problema este en ke incrementas mas cantidad en alguna de las coordendas.

Salu2...
Título: [vb6] Caminar En Diagonal?
Publicado por: Lord Trancos 2 en 31 de Julio de 2004, 11:24:51 AM
 EX3, lo que dices no es cierto. Aunque muchisimos juegos lo hacen asi y no le damos importancia. (En mi opinion no es algo que quede mal).

Te pongo un ejemplo en el mundo real. Tu tienes que ir desde donde estas, hasta una calle (imaginemos que no hay edificios de por medio). A la misma velocidad, tardaras menos en llegar si vas "recto" que si vas en diagonal.

Mientras que en el caso que comentas, si la calle es una linea horizontal en la parte inferior de la pantalla, tardarias lo mismo con X = X + 1, Y = Y + 1, que con Y = Y + 1.

La solucion que yo veo es usar Doubles para almacenar las posiciones del personaje, y modificar su posicion en funcion del tiempo y no 1 pixel cada X frames. Despues cuando lo quieres dibujar; conviertes la posicion a enteros y ya esta (o si estas en un modo 3D no hace falta).
Título: [vb6] Caminar En Diagonal?
Publicado por: Lord Trancos 2 en 31 de Julio de 2004, 11:33:39 AM
 Otra cosa. Usando Doubles, para mover en diagonal seria por ejemplo....

 X = X + (cos(Pi/4) * tiempo * velocidad)
 Y = Y + (sin(Pi/4) * tiempo * velocidad)

Y para mover recto por ejemplo...

 X = X + (tiempo * velocidad)

etc...
Título: [vb6] Caminar En Diagonal?
Publicado por: shephiroth en 03 de Agosto de 2004, 12:45:10 AM
 Muy buenas.

Aqui les pongo mi pequeño codigo, q es el q voya usar en mi rpg xDD

void moviendoJugador()
{
int cantidad =0;
if (keys[teclado.arriba]) cantidad++;
if (keys[teclado.abajo]) cantidad++;
if (keys[teclado.izquierda]) cantidad++;
if (keys[teclado.derecha]) cantidad++;
if (cantidad>=3 || cantidad==0) return;

//aqui faltan algunas comprobaciones, pero no vienen al caso

float muto=getMovimiento();
if (cantidad==2) muto=muto*2/3;
if (keys[teclado.arriba]) pjs->moverArriba(muto);
if (keys[teclado.abajo]) pjs->moverAbajo(muto);
if (keys[teclado.izquierda]) pjs->moverIzquierda(muto);
if (keys[teclado.derecha]) pjs->moverDerecha(muto);
}


El codigo me parece es bastante sencillo.
keys es un array booleano q marca cuando una tecla esta pulsada.
teclado. es una estructura q guarda todas las teclas q utiliza el juego.
pjs es un puntero al personaje en cuestion
getMovimiento() me da cuantos pixeles se ha de mover el muñaco en funcion del tiempo transcurrido desde la ultima llamada

Ademas, creo q el codigo te cuadraría perfecto, pq como ves ahi podrías meter codigo exclusivo para el diagonal, puesto q cuando hay 2 teclas presionadas es pq quiere hacer diagonal (de ahi habría q sacar cuando presiona arriba y abajo a la vez, pero me da igual xDD)
Título: [vb6] Caminar En Diagonal?
Publicado por: gdl en 03 de Agosto de 2004, 10:48:08 AM
 
'Amos a ver. ¿No sería más fácil hacer esto?


int deltaX=0, deltaY=0;
int velocidad=pj->VelocidadDelBicho();

if (keys[teclado.arriba]) deltaY-=velocidad;
if (keys[teclado.abajo]) deltaY+=velocidad;
if (keys[teclado.izquierda]) deltaX-=velocidad;
if (keys[teclado.derecha]) deltaX+=velocidad;

pj->MueveBicho(deltaX,deltaY);


Título: [vb6] Caminar En Diagonal?
Publicado por: jpastor en 03 de Agosto de 2004, 04:58:25 PM
 Sí, eso está más o menos bien, pero si quieres ser más realista hay que fijarse en lo que dice Lord Trancos 2.

El problema es que para el caso de que velocidad=1, si te mueves a la derecha, izquierda, arriba o abajo mueves el personaje 1 (una) unidad. Mientras que si lo mueves en diagonal lo mueves 1.414.. (sqrt 2), es decir, más rápido.
Título: [vb6] Caminar En Diagonal?
Publicado por: Pogacha en 04 de Agosto de 2004, 12:24:20 AM
 Se me ocurre mas mejor:

real t = Tiempo_Del_Frame * Escala_De_Aceleracion;  // tiempo del frame en segundos

struct v { real x, y } // velocidad del personaje
struct p { real x, y } // posicion del personaje
real m; // modulo de velocidad

if(key[Arr]) v.y+=t;
if(key[Aba]) v.y-=t;
if(key[Izq]) v.x-=t;
if(key[Der]) v.x+=t;

m= sqrt(v.x*v.x + v.y*v.y);
if(m>Velocidad_Maxima)
{
  m=Velocidad_Maxima*Tiempo_Del_Frame/m;
  v.x*=m;
  v.y*=m;
}

Manejar_Colisiones_Colision(&p, &v) // en caso de colicion altera la velocidad, (deslizamiento o demas)

p.x+=v.x;
p.y+=v.y;

int x=Enterizar(p.x);
int y=Enterizar(p.y);

Dibujar_Bicho(x,y);

// aplico friccion, muy importante

real Friccion= 0.1

v.x*=Elevar(Friccion, Tiempo_Del_Frame);  // Friccion a la tiempo del frame
v.y*=Elevar(Friccion, Tiempo_Del_Frame);


De esta manera manejamos aceleracion del personaje y se movera mas lindamente.
Jugando con las constantes de aceleracion, friccion y velocidad maxima
vas a encontrar lo que buscas.

Despues faltaria ver la direccion en que se mueve para cada animacion y se me ocurre


real cosalpha = v.x / m;
real alpha = arccos(cosalpha);
if(v.y<0) alpha= - alpha;
int anim = Enterizar(alpha-(PI/8)) % 8;


y las animaciones correspondientes a cada velocidad serian:

3 2 1
4 X 0
5 6 7

Espero que te sirva.

Saludos
Pogacha
Título: [vb6] Caminar En Diagonal?
Publicado por: shephiroth en 04 de Agosto de 2004, 02:02:15 PM
 Muy buenas. GDL yo al principio lo hacia como tu dices, obtenia el movimiento y se lo aplicaba en cada direccion sin tener en cuenta cuantas teclas tiene presionadas. Al final tuve q modificar el codigo pq me interesaba saber cuando hay mas de una tecla presionada. Recordemos que ABC7 quiere que su muñeco ande en diagonal, asi que tendrá que saber cuando hay dos teclas presionadas.

Pogacha, tu código me parece bastante complejo, pero va un poco más allá de lo que se pedía (creo yo). Para un juego de coches, de naves, de carreras......tu codigo es perfecto, puesto que tienes en cuenta todos los factores que hay q tener encuenta en ese tipo de juegos. Pero ABC7 quiere mover un muñeco, por lo q creo que tienes encuenta demasiados factores. Por otra parte utilizas mucho las funciones de seno, coseno, tangente......y actualmente cuantas menos operaciones con coma flotante hagamos hacer al ordenador mejor.

ABC7 como ves tienes codigo para elegir. Complicado pero compacto codigo de Pochanga, codigo simple pero directo de GDL, o mi codigo un poco mas elaborado pero no demasiado completo. Luego tienes ideas por ahi que deberías tener en cuenta.

Bueno, ya nos comentarás el codigo final que uses, la cosa puede quedar guapa  (nooo)  
Título: [vb6] Caminar En Diagonal?
Publicado por: Pogacha en 04 de Agosto de 2004, 04:19:43 PM
 El tema de las operaciones, si conte bien, son solamente un sqrt, un arcos, y dos pow por frame, eso se hacia en un spectrum, en un pc debe andar mas todavia.

Señor ABC7, creo que hay codigo para que te entretengas.

Saludos Pogacha

Título: [vb6] Caminar En Diagonal?
Publicado por: shephiroth en 04 de Agosto de 2004, 04:39:04 PM
 Pogacha, el problema no es que ahi haya esas minimas operaciones de mas (como dices son una chorrada), el problema es cuando hay unas pocas aqui, otras allá...........el problema tampoco esta en los juegos pequeños, pues no son tan extensos como para acumular tantas "operaciones extra"..........sino el problema viene en los juegos grandes que van acumulando estas operaciones, y es lo que hace que un juego necesite un p4 a 3000 en vez de un p3 a 500 para funcionar de forma fluida (me he pasado, lo se  (twist) )

Weno, nada mas. Este post solo era para concienciar sobre el buen uso del cpu en los programas.....hasta yo lo hice mal, puse 2/3 en vez de precalcular el valor 1 sola vez, pero bueno xDD

SALUDOS
Título: [vb6] Caminar En Diagonal?
Publicado por: Pogacha en 04 de Agosto de 2004, 05:30:52 PM
 Si eso pensaba antes yo, pero en realidad no importa, te muestro:
No le prestes atencion al codigo, si a los bucles:


for i=0 to 10
A=10*i
B=30*i + 3*i
Z = Funcion_Rara(A+B);
C = Delta[i]
for j=0 to 100000
  Z=Z+j*C;
next j
Epsilon[j]=Z
next i


Esto demora  10 * ( 20 + 100000  * 3 ) =  3000200

y si lo arreglas :


rem   A + B = i * 10 + i * 3 + i * 30  
rem   =>
rem   A+B= i * 43
rem   y
rem    i=i+1
rem   =>
rem  (A+B)=(A+B)+43  
rem   Con B superfluo
rem   A=A+43


A=0
for i=0 to 10
A=A+43
Z = Funcion_Rara(A);
C = Delta[i]
for j=0 to 100000
  Z=Z+j*C;
next j
Epsilon[j]=Z
next i

Esto demora  10 * ( 4 + 100000  * 3 ) =  3000040

Y me cago en la diferencia.

Prefiero dedicar mi tiempo a bajar la demora de los bucles pesados,
lo que se hace una vez por frame no tiene importancia que demore 1 o 10 uSeg,
pero esto es otro tema.

Saludos
Pogacha
Título: [vb6] Caminar En Diagonal?
Publicado por: gdl en 05 de Agosto de 2004, 10:58:31 AM
 
Mmm.... si quisiera saber si dos teclas están pulsadas, por ejemplo para ajustar la velocidad en diagonal a raíz de dos, haría una cosa como esta (que sigue siendo simple):

int deltaX=0, deltaY=0;
int velocidad=pj->VelocidadDelBicho();

if (keys[teclado.arriba]) deltaY-=velocidad;
if (keys[teclado.abajo]) deltaY+=velocidad;
if (keys[teclado.izquierda]) deltaX-=velocidad;
if (keys[teclado.derecha]) deltaX+=velocidad;

if((deltaX|deltaY)!=0)//Realmente el !=0 sobra, pero para que quede claro
{
 //Ohhh dos teclas pulsadas, corrijo velocidad para diagonal.
 deltaX=deltaX*5/7;//5/7 es más o menos dividir por raíz de dos.
 deltaY=deltaY*5/7;//No lo precalculo porque uso enteros.
}

pj->MueveBicho(deltaX,deltaY);


Aunque, ahora que lo pienso, si se pulsan dos teclas como izquierda y derecha a la vez, no lo detecta.... claro que como no quieras implementar una mitosis o algo así, no te va a hacer falta.

También veo que usar *5/7 añade una multiplicación y una división extra, que se pueden evitar si precalculas la velocidad en la diagonal. En fin, eso liaría el código y si ABC7 quiere, que se ponga a optimizar.

Y, para ser sinceros, yo suelo usar flotantes en un código como el de Pogacha (versión más mejor), que tiene el cuenta la duración del frame y todo ese follón.
Título: [vb6] Caminar En Diagonal?
Publicado por: Pogacha en 07 de Agosto de 2004, 06:18:21 PM
 Creo que el codigo anterior es los mas parecido a lo que ABC7 buscaba, el tema era como organizar el movimiento.

si queres optimisar:

en C:

usando un fixed point de 16:16

#define F_B 16
#define RAIZ_DE_DOS_SOBRE_DOS   0.70710678118654752440084436210485

#define F_RAIZ_DE_DOS_SOBRE_DOS   int(0.70710678118654752440084436210485*(1<
Vel = (Vel * F_RAIZDEDOSSOBREDOS)>>F_B;

Pero acordate, es una vez por frame, ¡que importa!
y despues con decir

if (DeltaX || DeltaY)  // sobra y es mejor para el compilador





Título: [vb6] Caminar En Diagonal?
Publicado por: shephiroth en 11 de Agosto de 2004, 02:10:28 PM
 Buenas.

Pochanga, no me referia a evitar operacion como las q dices, con enteros funciona igualmente. Pero create un programa, ponle contador de tiempo, y haz el mismo codigo CON DECIMALES, ya veras q en ambos casos no te da la misma velocidad.

No se si los ordenadores ultimo modelo ya tendán el problema superado......si tienes la oportunidad compilate el programa, y pruebalo en un p2 o p3, en los amd k6 y k6-2 ya era la risa xDD

Weno, un saludo ^^

EDITADO:

Por cierto, para evitar dos teclas iguales, yo utilizo algo como
if (keys[teclado.arriba] && keys[teclado.abajo] || keys[teclado.izquierda] && keys[teclado.derecha]) return;
Título: [vb6] Caminar En Diagonal?
Publicado por: gdl en 12 de Agosto de 2004, 10:11:51 AM
 Confirmado: estoy apamplado,

creo que el código funcionaría (ni mejor ni peor, porque el otro de arriba no funcionaba) si ponemos


int deltaX=0, deltaY=0;
int velocidad=pj->VelocidadDelBicho();

if (keys[teclado.arriba]) deltaY-=velocidad;
if (keys[teclado.abajo]) deltaY+=velocidad;
if (keys[teclado.izquierda]) deltaX-=velocidad;
if (keys[teclado.derecha]) deltaX+=velocidad;

if(!(deltaX || deltaY))
 return;//Por sugerencia de shephiroth

if(deltaX && deltaY)
{
//Ohhh dos teclas pulsadas, corrijo velocidad para diagonal.
 deltaX=(deltaX * F_RAIZDEDOSSOBREDOS)>>F_B;//Por sugerencia de Pogacha
 deltaY=(deltaY * F_RAIZDEDOSSOBREDOS)>>F_B;
}

pj->MueveBicho(deltaX,deltaY);


Mira que poner un OR para ver si dos teclas (una *Y* otra) estaban pulsadas.

Luego me tiro meses depurando....  (nooo)