Karoshi MSX Community
05 de Julio de 2021, 07:47:27 pm *
Bienvenido(a), Visitante. Por favor, ingresa o regístrate.

Ingresar con nombre de usuario, contraseña y duración de la sesión
Noticias:
 
   Inicio   Ayuda Buscar Ingresar Registrarse  
Páginas: [1] 2
  Imprimir  
Autor Tema: Saltos y caidas  (Leído 12172 veces)
0 Usuarios y 1 Visitante están viendo este tema.
burguera
Visitante
« : 11 de Octubre de 2006, 10:24:52 am »

Estaba acabando de pulir la gestión de movimientos del personaje en mi juego de plataformas, y me ha surgido la duda sobre opciones para los saltos y caidas. Lo que he hecho (y sobre lo que leí creo que en estos foros) es lo siguiente. Tengo una tabla de saltos/caidas del estilo de la siguiente:

Código:
RPJMP: db -3,-3,-2,-2,-2,-1,-2,-2,-1,-2,-1,-1,0,0,0
       db 0,0,0,1,1,2,1,2,2,1,2,2,2,3,3

Cada posición indica lo que tengo que sumar o restar a la coordenada Y del jugador. Es decir, en cada iteración del bucle principal hago algo tal que

Código:
Y=Y+RPJMP[index]
index=index+1

Cuando el personaje va a saltar, inicio index a 0. I cuando empieza a caer, lo inicio a 15.

¿Que otras técnicas usáis vosotros?

Por otro lado, para el control del personaje me decidí por una máquina de estados (o Autómata Finito Determinista, Nerlaska ;-), y es bastante cómoda.

Saludos
En línea
nerlaska
Karoshi Excellent Member
******
Mensajes: 1102


Programador


WWW Email
« Respuesta #1 : 11 de Octubre de 2006, 10:41:14 am »

Si al final te harás un crack ;-)

Lo de los saltos .. hombre .. puedes montarlo restando un tiempo o hasta colisión (en la subida) y restando hasta colisión (en la bajada) sin necesitad de tablas.
Algo más o menos de la siguiente manera .. teniendo en cuenta que tienes 2 estados .. el de SALTANDO (JUMPING) y el de caida (FALLING) ...

switch (player.state)
{
    ....

   case PLAYER_STATE_JUMPING:
   {
      if (jump_timer > 0 && Player_Up_Collision () ==  false)
      {
         jump_timer--;
         player.y -= PLAYER_JUMP_SPEED;
      }
      else
      {
         player.state = PLAYER_STATE_FALLING;
         player.frame = PLAYER_FRAME_FALLING;
      }
   }
   break;
   case PLAYER_FALLING:
   {
       if (Player_Down_Collision () == false)
       {
          player.y += PLAYER_JUMP_SPEED;
       }
       else
       {
          player.state = PLAYER_STATE_QUIET;
          player.frame = PLAYER_FRAME_QUIET;
       }
   }
   break;
}

Algo así más o menos :-)
En línea

MSX4EVER2GETHER
www.nerlaska.com
burguera
Visitante
« Respuesta #2 : 11 de Octubre de 2006, 10:45:05 am »

Yes. De momento tengo cuatro estados: andando, saltando, cayendo y esperando. Este último es, simplemente, un estado de espera entre los saltos. Más adelante deberé añadir el estado de subir escaleras.

De todas formas, el código que propones salta y cae a velocidad constante. Yo estaba hablando de tener una velocidad no constante: que a la subida vaya frenando poco a poco y a la bajada vaya acelerando. Esto es lo que consigo con la tabla anterior.
En línea
nerlaska
Karoshi Excellent Member
******
Mensajes: 1102


Programador


WWW Email
« Respuesta #3 : 11 de Octubre de 2006, 10:55:43 am »

Si bueno .. porque la velocidad es constante .. pero puedes tener una variable aceleración/deceleración y te sirve igual.
En línea

MSX4EVER2GETHER
www.nerlaska.com
jjfranco
Visitante
« Respuesta #4 : 11 de Octubre de 2006, 11:14:35 am »

Pues a mi me gustaria ayudarte

Para realizar lo que estas diciendo tan solo tienes que aplicar la formula del tiro parabolico en el eje "y", y aplicar el movimiento rectilineo y uniforme en el eje "x". Esto siginifica que tendras un momiento acelerado en el eje "y" y un movimiento con velocidad constante en el eje "x".

la formula para el movimiento parabolico es

y=yo+vo*t+1/2*a*t^2

donde "yo" seria la posicion "y" del personaje en ese momento (que se podría eliminar si realizas una tabla de movimientos relativos, tal como propones)

"vo" seria la velocidad del impulso del muñeco al iniciar el salto que seria constante a elegir por ti

y "a" seria la aceleracion que la tierra ejerce sobre el muñeco (9.8 m/s^2) que tambien es constante, por lo que te quedaria la ecuacion del siguiente modo

y=vo*t+4.9*t^2

en esta formula dando valores a t, que seria el tiempo, obtendras diferentes valores de y, que serian los valores que deberias incluir en la tabla (db valor1, valor2, valor3, etc) cuantos mas valores incluyas y cuantos mas cercan esten unos valores (de t me refiero) de otros mas suave sera el movimiento, conseguiras el efecto de un salto parabolico acelerado.

y respecto al movimiento en el eje "x", se podria hacer simplemente sumando siempre un mismo valor constante, puesto que el movimiento es a velocidad constante, si deseases tambien incluir aceleracion en este eje, se podría volver a aplicar la formula del tiro parabolico.

Creo que con este metodo puedes conseguir un efecto mas realista para el movimiento de tu programa.

Espero que mi propuesta sirva para ayudarte en algo, y creo que con tan solo una tabla puedes conseguir el efecto de aceleracion que deseas.

Un saludo.
En línea
jltursan
Karoshi Forum's Guru
*******
Mensajes: 1516


¿Que es lo que has aprendido hoy?


WWW Email
« Respuesta #5 : 11 de Octubre de 2006, 11:34:02 am »

Ese es más o menos el criterio que seguí en el "Caverns of Titan"; por aquello de no complicarme mucho utilicé una tabla de salto fija como la que se describe, la diferencia es que ya que la amplitud del salto no superaba (no debía) los 20 píxeles no me compliqué la vida y use los valores del seno, que no describen un salto real; pero para el caso daban el pego.
El mejor modelo que se puede usar es el cálculo en tiempo real, tal como explica Nerlaska, utilizando aceleración y aritmética de coma fija; si no recuerdo mal, en el Pong512 de Sapphire hay un buen ejemplo del uso de esta última técnica.
En línea

Doom dee doom dee doom
pitpan
Karoshi Forum's Guru
*******
Mensajes: 1812


« Respuesta #6 : 11 de Octubre de 2006, 11:34:33 am »

...pero te puedes ahorrar la variable t, tiempo, dado que estás realizando los cálculos en tiempo real.

Por ejemplo, defines una velocidad de caída inicial de VY=1.

Y en tanto se mantenga el estado caída, puedes hacer VY=VY+0.02 (ajústalo según tus intereses). También puedes establecer un máximo de velocidad de caída (una velocidad terminal, como sucede en las caídas reales), tipo IF VY>2.5 THEN VY=2.5

Este no es un mal modelo, ya que la caída es un movimiento con aceleración constante (g=9,8). Por lo tanto, el incremento de la velocidad será lineal y función del tiempo, esto es, una integral de la aceleración. Por lo tanto, Vt+1=Vt+k. Sólo te hace falta ajustar los valores a la escala del juego.

Después, claro está, Y=Y+VY.

No es muy complicado, pero tienes que implementarlo todo utilizando aritmética de punto fijo (es lo más cómodo). Afortunadamente, para esto se incluyó el soporte de punto fijo en el ensamblador asMSX, que es mucho más rápido que utilizar punto flotante y funciones aritméticas complejas. Es decir, puedes hacer cosas hermosas como

INCREMENTO_VELOCIDAD_CAIDA: dw fix(0.25)

Que sería equivalente a dw 0040h

En línea
SapphiRe
Visitante
« Respuesta #7 : 11 de Octubre de 2006, 11:38:44 am »

El mejor modelo que se puede usar es el cálculo en tiempo real, tal como explica Nerlaska, utilizando aceleración y aritmética de coma fija; si no recuerdo mal, en el Pong512 de Sapphire hay un buen ejemplo del uso de esta última técnica.

Simplemente indicar que en el Pong512 sólo trabajo con la posición X,Y de la bola y el vector velocidad. No hay una aceleración tal cual, simplemente que el vector velocidad ve incrementado su módulo (y modificada su dirección) cada vez que la pelota incide en uno de los bates hasta una velocidad máxima.

El caso es que da el pego Grin Grin
En línea
Jon_Cortazar
Administrator
Karoshi Forum's God
********
Mensajes: 2777



WWW Email
« Respuesta #8 : 11 de Octubre de 2006, 11:49:59 am »

¿Que otras técnicas usáis vosotros?
Pues yo, en mi caso, la mismita que tu  Wink. Un puntero que avanza sobre unos valores positivos/negativos en una lista que se suman a Y.
En línea

Jon Cortázar Abraido (aka El Viejo Archivero)
RELEVO Videogames
[Dioniso: La cafeína está haciendo su trabajo; yo espero hacer el mío.]
[pitpan: Me sigue pareciendo más productivo jugar al SNAIL MAZE que seguir esta discusión.]
WYZ
Visitante
« Respuesta #9 : 11 de Octubre de 2006, 11:54:26 am »

Sapph , pero di que me copiaste la idea en esa Ru de Murcia  Cheesy. El caso es que despues la mejoraste bastante simplificando la tabla de modulos para que cupiese en 1024bytes! Yo creo que incluso podrias haberle incluido FX y música a ese pong, alguna variación en los gráficos (*)... en fin una lástima  Grin ...

(*) Ponle el Cheat Jon!! Grin
En línea
Jon_Cortazar
Administrator
Karoshi Forum's God
********
Mensajes: 2777



WWW Email
« Respuesta #10 : 11 de Octubre de 2006, 11:56:46 am »

(*) Ponle el Cheat Jon!! Grin

Que lo pongo!, eh?.. Que lo pongo!  Cheesy Cheesy Cheesy Cheesy
En línea

Jon Cortázar Abraido (aka El Viejo Archivero)
RELEVO Videogames
[Dioniso: La cafeína está haciendo su trabajo; yo espero hacer el mío.]
[pitpan: Me sigue pareciendo más productivo jugar al SNAIL MAZE que seguir esta discusión.]
burguera
Visitante
« Respuesta #11 : 11 de Octubre de 2006, 11:57:03 am »

A ver que me aclare... usando aritmética en punto fijo, y, por ejemplo, haciendo vy=vy+0.02 y, claro, y=y+vy, tendré vy (y por lo tanto, y) con decimales. Obviamente habrá que redondear al final, para no perder precisión que para este caso es crítica. Esto provocará que, por el redondeo, los valores que pueda tener "y" sean del estilo 10,11,11,12,12,12,12,... donde el primer once, por ejemplo, se corresponde al redondeo de 11.1, el segundo al redondeo de 11.9 y así. ¿Correcto?

Esto es equivalente a tener una tabla de incrementos del estilo 0,1,0,1,0,0,0. Ya digo, quizás los números de ejemplo que he puesto no son muy buenos pero la idea se pilla, ¿no?

Entonces no hace falta usar aritmética en punto fijo ni nada. Se precalculan los valores de incrementos ya redondeados y listos. Claro, si se supone que la velocidad de caida puede crecer indefinidamente puede resultar una tabla de salto muy grande. Pero, como comenta robsy, hay una velocidad máxima de caida.

No se si me he explicado. Quiero decir que no veo la ventaja de hacer los cálculos on-line con las fórmulas y aritmética en punto fijo respecto a tener una tabla precalculada de velocidades ya redondeadas.
En línea
SapphiRe
Visitante
« Respuesta #12 : 11 de Octubre de 2006, 11:58:30 am »

WYZ, claro que sí. Te pregunté cómo lo hacías tú y me pasaste una tabla que luego optimicé lo más que pude para que resultase lo más pequeñita posible. Aún hay unos 19 bytes libres... ¿alguna sugerencia?

(*) CHEAT, CHEAT! CHEAT! cmptr:) :whip:
En línea
SapphiRe
Visitante
« Respuesta #13 : 11 de Octubre de 2006, 12:02:38 pm »

A ver que me aclare... usando aritmética en punto fijo, y, por ejemplo, haciendo vy=vy+0.02 y, claro, y=y+vy, tendré vy (y por lo tanto, y) con decimales. Obviamente habrá que redondear al final, para no perder precisión que para este caso es crítica. Esto provocará que, por el redondeo, los valores que pueda tener "y" sean del estilo 10,11,11,12,12,12,12,... donde el primer once, por ejemplo, se corresponde al redondeo de 11.1, el segundo al redondeo de 11.9 y así. ¿Correcto?

Correcto, solo que el redondeo no es necesario ya que en el byte superior tienes la parte entera y en el inferior la parte decimal (número de doscientos cincuentaavos de entero).

Citar
Esto es equivalente a tener una tabla de incrementos del estilo 0,1,0,1,0,0,0. Ya digo, quizás los números de ejemplo que he puesto no son muy buenos pero la idea se pilla, ¿no?

Exacto. Los incrementos estarán en forma de dos bytes: uno para la parte entera y otro para la parte decimal, claro que puedes ahorrarte los bytes de la parte entera si todos los incrementos son decimales... Roll Eyes de qué me suena eso... Roll Eyes

Citar
Entonces no hace falta usar aritmética en punto fijo ni nada. Se precalculan los valores de incrementos ya redondeados y listos. Claro, si se supone que la velocidad de caida puede crecer indefinidamente puede resultar una tabla de salto muy grande. Pero, como comenta robsy, hay una velocidad máxima de caida.

No se si me he explicado. Quiero decir que no veo la ventaja de hacer los cálculos on-line con las fórmulas y aritmética en punto fijo respecto a tener una tabla precalculada de velocidades ya redondeadas.

¿Quién ha dicho que ambas aproximaciones hayan de ser excluyentes? Con aritmética de punto fijo puedes hilar más fino y mover tu personaje 3/4 de pixel si te lo propones Cheesy
En línea
pitpan
Karoshi Forum's Guru
*******
Mensajes: 1812


« Respuesta #14 : 11 de Octubre de 2006, 12:11:15 pm »

Claro! Como dice Sap, sólo hay que coger el byte alto del resultado, pero tienes que mantener en memoria el valor completo (2 bytes).

Por ejemplo

; Incrementa la velocidad
ld hl,[VY]
ld bc,fix(0.02]
add hl,bc
ld [VY],hl

; Ajusta posicion

ex de,hl
ld hl,[Y]
add hl,de
ld [Y],hl

; Obtiene la coordenada de pantalla

ld a,h

Algo así debería funcionar. Igual se me ha colado alguna morcilla, verificadlo. Y la precisión que pierdes es muy poca.


En línea
Páginas: [1] 2
  Imprimir  
 
Ir a:  

Impulsado por MySQL Impulsado por PHP Powered by SMF 1.1.21 | SMF © 2013, Simple Machines XHTML 1.0 válido! CSS válido!