Karoshi MSX Community

Desarrollo MSX => Desarrollo (Español/Spanish) => Mensaje iniciado por: OKI09 en 01 de Octubre de 2008, 11:18:20 am



Título: Parabola
Publicado por: OKI09 en 01 de Octubre de 2008, 11:18:20 am
Pues eso, cual es la forma mas facil para mover un sprite en forma de parabola. ???

Robsy, a ti te salieron muy bien las de el juego de 2Kbos, como las hiciste.


Título: Re: Parabola
Publicado por: pitpan en 01 de Octubre de 2008, 12:03:02 pm
Pues la parábola no es más que un movimiento uniformemente acelerado. Para entendernos, te lo pintaré en pseudo-código:

angulo=45*pi/180;VI=20;X=0;Y=192;VX=VI*cos(angulo);VY=-VI*sin(angulo);g=0.02;

bucle:
VY=VY+g;
Y=Y+VY;
X=X+VX;

Como verás, es fácilmente trasladable a ensamblador. La única parte complicada es que hay que usar aritmética de punto fijo. Pero al final es una cosa muy sencilla:

2,5 en decimal = 2 + 0,5 = 2^1 + 2^-1

Se representa la parte entera en el byte alto y la parte decimal en el bajo, y ya lo tienes. 2,5 = 0000 0010 - 1000 0000 b = 0280h

Afortunadamente, el asMSX te permite hacer la conversión directa con la función fix(). Y los senos y cosenos mediante una tabla para evitarte así cálculos raros.

Te recomiendo que destripes el código fuente del G-MONKEY y también, aunque sea más sencillo, una demo de aritmética de punto fijo que estaba en una distribución anterior del asMSX, y que creo que se llamaba G.ASM o algo así.




Título: Re: Parabola
Publicado por: Jon_Cortazar en 01 de Octubre de 2008, 12:09:49 pm
Que casualidad, yo también ando trasteando con la aritmética de punto fijo. Así que fix() te ajusta automáticamente la parte decimal, ahora lo entiendo ;)


Título: Re: Parabola
Publicado por: pitpan en 01 de Octubre de 2008, 01:36:02 pm
Efectivamente, socio. asMSX utiliza aritmética de punto flotante de doble precisión para sus cálculos internos y después se puede convertir todo número a formato de punto fijo con fix(). La idea es la misma que para enteros: el bit más significativo vale 2^7, mientras que el menos significativo dentro de la palabra de 16 bits, vale 2^-8. Por lo tanto, en valor absoluto, el mayor valor representable sin signo sería 255,996 aproximadamente y el más pequeño 0,00390625, que coincide con la precisión de este formato.

La ventaja es que se pueden sumar directamente como enteros de 1 bits y el resultado es correcto. Podría hacerse lo siguiente:

Código:
ld hl,fix(2.50)
ld de,fix(1.75)
add hl,de
ld bc,fix(0.33)
add hl,bc

El valor contenido en los distintos registros al final de la ejecución sería el siguiente:

BC = 00 55 h
DE = 01 C0 h
HL = 04 94 h

Además, se pueden hacer restas del mismo modo, entendiendo entonces que los números tienen signo y están representados en complemento a dos.

Para hacerlo más fácil de entender, el asMSX además incluye la pseudoinstrucción PRINTFIX, que permite ver el valor en formato de punto fijo. Y se puede comparar entonces con PRINTHEX y lo que indica.

Supongo que se podría dar alguna explicación un poco más detallada, pero no dispongo de tiempo ahora para hacer un artículo al respecto.

Para hacer una tabla de senos para los ángulos comprendidos entre 0 y 90, bastaría con hacer lo siguiente:

Código:
SIN_TABLE:
  angulo=0
  rept 91
    dw fix(sin(angulo*pi/180.0))
    angulo=angulo+1
  endr

Así tendríamos una maravillosa tabla de 91 x 2 = 182 bytes recogiendo el valor del seno para cada ángulo entre 0 y 90 grados, o lo que es lo mismo, entre 0 y pi/2 radianes. Por cierto, que el valor PI está definido por defecto en asMSX. ;)



Título: Re: Parabola
Publicado por: OKI09 en 01 de Octubre de 2008, 02:55:29 pm
Vale, mas o menos entendido, pero yo me aclaro mejor viendo un ejemplo y destripandole un poco. ;D

Me puedes enviar esos dos ejemplos que me dices Robsy, el codigo de el G-Monkey no le veo para poder descargarlo.

Perdona por las molestias.


Título: Re: Parabola
Publicado por: ARTRAG en 01 de Octubre de 2008, 08:08:13 pm
FYI
http://www.msx.org/forumtopic8523.html


Título: Re: Parabola
Publicado por: kabish en 01 de Octubre de 2008, 08:32:28 pm
No se site servira esto ..

http://msxgamesbox.com/karoshi/index.php?topic=451.15


Título: Re: Parabola
Publicado por: pitpan en 02 de Octubre de 2008, 07:48:25 am
Distribución del G-MONKEY (http://www.robsy.net/g-monkey.zip) con código fuente.

Última distribución oficial del asMSX v.0.12g (http://www.robsy.net/asmsx012g.zip) - en la carpeta Examples encontrarás el fichero fixed.asm. Para ensamblar, mejor usar la última beta porque es bastante más estable.

Con esto debería bastar.


Título: Re: Parabola
Publicado por: Jon_Cortazar en 02 de Octubre de 2008, 11:22:13 am
Ya verás la que estoy preparando, ya... muahahahaha!


Título: Re: Parabola
Publicado por: pitpan en 02 de Octubre de 2008, 11:48:25 am
Y no nos puedes dar ni una pistilla? Ni siquiera a tu pobre socio?  :'(


Título: Re: Parabola
Publicado por: Saeba en 02 de Octubre de 2008, 08:26:00 pm
Aritmética de punto fijo???

[Modo publicidad ON]

Sólo puedo acordarme de este ejemplar y ese peaaaassso artículo de Avelino sobre ese tema:

http://callmsx.atlantes.org/7 (http://callmsx.atlantes.org/7)


Título: Re: Parabola
Publicado por: Ramones en 03 de Octubre de 2008, 09:15:43 am
Senos? Cosenos? Punto fijo? XDDD

Está claro que para movimientos complicados simulando elipses y círculos me parece correcto usar todo esto. Pero para una parabola "sencillita" no hace falta NADA de todo eso. :D Os lo aseguro, si vieseis como las hago en el Pang os partís el pecho.

Ni un seno, ni un coseno ni nada de nada. Todo depende de la complejidad que le quieras dar (y sobre todo la precisión que busques).

Creo que es mucho mas sencillo pensarlo de otra manera. En las bolas del Pang (por poner un ejemplo) el vector de aceleración X es fijo. Es decir cada bola se mueve con una velocidad X fija. Entonces solo falta la Y. Y la velocidad de "impulso" Y pues también estaba fijada por bola. (el maximo)

Entonces con esto, qué tenemos? Pues imaginando que la bola empieza desde arriba de la pantalla sencillamente hago esto:

VY = 0
X = la que sea
Y = 0
VX = la fijada, imaginemos 1
G = 1 (gravedad al gusto)

bucle:

X =X + VX
Y = Y + VY
VY = VY + G

De esta forma al caer se va acelerando. Si detectaba que "se pasaba" de vueltas, pues la dejaba con un tope de velocidad VY.

Y cuando toca suelo, pues invertimos:

X = X + VX
Y = Y - VY
VY = VY - G

Y nada, que si llega a 0 la VY pues le vuelvo a dar la vuelta.

CHAPUZA? MUUUUCHA!! :D Es un chapuzón como la copa de un pino. Hoy en día ya uso movimientos uniformemente acelerados y senos y cosenos para movimientos de sprites y demás.

Pero os aseguro que ESO que he puesto funciona perfectamente, los calculos son ínfimos y no hay que usar punto fijo, ni tablas de senos y cosenos. Todo depende de las necesidades del programa claro.












Título: Re: Parabola
Publicado por: OKI09 en 03 de Octubre de 2008, 09:51:59 am
Gracias a todos, todas estas explicaciones y tecnicas me han venido de perlas. :D

Ramones, voy a darle vueltas a tu solucion, a lo mejor no necesito nada mas, pues es un efecto sencillo el que quiero hacer. ;)


Título: Re: Parabola
Publicado por: pitpan en 03 de Octubre de 2008, 10:54:51 am
Ramones: estoy contigo. No hace falta usar ni seno ni coseno para nada, si puedes determinar la velocidad inicial en los ejes X e Y directamente. Si miras el pseudocódigo que indiqué, sólo se usaban para el cálculo de la velocidad inicial, tal y como lo hice en el G-MONKEY, donde era imprescindible: a cada ángulo le corresponde una velocidad distinta en los ejes X e Y.

Estamos de acuerdo en que no se necesitan para nada más. Si quitas este detalle, verás como la solución que propones es equivalente a la mía. ;)


Título: Re: Parabola
Publicado por: Ramones en 03 de Octubre de 2008, 12:15:19 pm
Estamos de acuerdo en que no se necesitan para nada más. Si quitas este detalle, verás como la solución que propones es equivalente a la mía. ;)

En efecto, estamos de acuerdo. Yo solo intentaba no "asustar" a OKI con puntos fijos y senos y cosenos que es algo que puede asustar al programador novel.

Realmente para calcular una parábola no hace falta mucho más. Luego ya depende de la complejidad que quieras darle. Si quieres tener un impulso inicial y por ejemplo un punto de inicio y final de la misma pues el cálculo ya es mucho más complejo (aunque se puede precalcular antes y usarlo despues).

Si quieres que se ejecute en un tiempo determinado pues el cálculo es de otra forma. Si quieres que alcance una altura dada, pues es de otra manera. Pero en ninguno de esos calculos se necesitan senos y cosenos. Eso si, decimales, cuantos más pues mejor precisión. :)

Y como bien dices en tu GMONKEY te era obligado usarlos por el hecho de utilizar grados para tirar los plátanos. :) Es obvio.






Título: Re: Parabola
Publicado por: pitpan en 03 de Octubre de 2008, 12:46:26 pm
Por cierto, que tendría que incluirle el efecto del viento al G-MONKEY. Creo que aún así me cabría en 2 KB. Aunque también es cierto que tengo cosas mejores que hacer :P


Título: Re: Parabola
Publicado por: k0ga en 03 de Octubre de 2008, 05:59:38 pm
Ramones: estoy contigo. No hace falta usar ni seno ni coseno para nada, si puedes determinar la velocidad inicial en los ejes X e Y directamente. Si miras el pseudocódigo que indiqué, sólo se usaban para el cálculo de la velocidad inicial, tal y como lo hice en el G-MONKEY, donde era imprescindible: a cada ángulo le corresponde una velocidad distinta en los ejes X e Y.

Estamos de acuerdo en que no se necesitan para nada más. Si quitas este detalle, verás como la solución que propones es equivalente a la mía. ;)

Joe, que la formula de la parabola es y=a*x^2+b*x+c, si derivamos obtenemos que dy/dx=2*a*x+b, es decir que el incremento del incremento es lineal, por lo que tal y como lo hace Armando es matematicamente correcto, es como se tiene que hacer, no es ninguna chapuza.

Yo usaba este tipo de cosas en el driver de microcabin, donde obtienen el seno de una manera parecida, gracias a una aproximacion del coseno (que es la derivada del seno).

Ahi teneis ;).







Título: Re: Parabola
Publicado por: kabish en 03 de Octubre de 2008, 06:05:29 pm
Si en su dia me hubieran explicado las derivadas con juegos de MSX, seguro que las hubiera entendido mejor.  :)


Título: Re: Parabola
Publicado por: pitpan en 03 de Octubre de 2008, 06:42:34 pm
¿Una fórmula de Taylor para el driver de sonido? Vaya tela. Estos japos se meten de todo.  :o


Título: Re: Parabola
Publicado por: Ramones en 04 de Octubre de 2008, 12:25:14 am
Joe, que la formula de la parabola es y=a*x^2+b*x+c, si derivamos obtenemos que dy/dx=2*a*x+b, es decir que el incremento del incremento es lineal, por lo que tal y como lo hace Armando es matematicamente correcto, es como se tiene que hacer, no es ninguna chapuza.

Yo usaba este tipo de cosas en el driver de microcabin, donde obtienen el seno de una manera parecida, gracias a una aproximacion del coseno (que es la derivada del seno).

Ahi teneis ;).


La chapuza viene de la poca precisión. Al no usar punto fijo los incrementos son de 1 mínimo (a no ser que los ejecutes cada x ints o algo así). Para afinar un poco esta fórmula y dar gravedades más interesantes (al igual que incrementos de X), pues se puede optar por pequeños puntos fijos sencillos que dan mucho más margen.

Un punto fijo sencillo de 4 bits, con 3 bits de parte entera y 1 de signo se puede hacer con 1 byte y te da bastante resolución para hacer cosas interesantes. Sin necesidad de usar 2 bytes (16 bits) con parte punto fijo y entera, que siempre es más costoso en los cálculos. Esto lo uso en los Goonies ahora mismo y me sobra para aceleraciones, saltos, etc...

el bit más alto lo uso de signo, los 3 siguientes de parte entera y los 4 más bajos de punto fijo. No es gran cosa, pero da buenos resultados, aunque te cuesta 4 srls cada vez que quieres sumar a las coordenadas finales, o bien sacar el valor entero. Pero es aceptable.

Pero que si, que la fórmula de la parábola no deja de ser la que tu has puesto. Y es que precisamente HOY me ha tocado implementar una en el curro pero un poco más compleja. Con punto inicial y final, y aceleración Y de salida como parámetro. Pero ahí ya tiro de floats así que no hay problemas con la resolución. Podría pasarlo a Z80 sin problemas si a alguien le interesa. Tiene un punto crítico que es el cálculo inicial pero luego solo queda la aceleración de los dos ejes (X e Y) que es lo que se va sumando en cada interrupción, vamos supersencillo y muy rápido.








Título: Re: Parabola
Publicado por: MsxKun en 04 de Octubre de 2008, 11:29:52 am
Pues no iria mal añadir estas cosas como Snippets, tarde o temprano acaban haciendo falta :)


Título: Re: Parabola
Publicado por: OKI09 en 04 de Octubre de 2008, 11:37:40 am
Ramones, puedes explicar mejor con un ejemplo (Si puedes, claro) como lo haces con un byte. No acabo de verlo claro. :-[

Gracias


Título: Re: Parabola
Publicado por: SapphiRe_MSX en 04 de Octubre de 2008, 02:07:56 pm
el bit más alto lo uso de signo, los 3 siguientes de parte entera y los 4 más bajos de punto fijo. No es gran cosa, pero da buenos resultados, aunque te cuesta 4 srls cada vez que quieres sumar a las coordenadas finales, o bien sacar el valor entero. Pero es aceptable.

¿Pero no usas RLD y RRD? ¡Con lo cómodas que son! :D :D