Karoshi MSX Community
06 de Julio de 2021, 12:12:21 am *
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]
  Imprimir  
Autor Tema: mover un algo de un punto a otro  (Leído 4994 veces)
0 Usuarios y 1 Visitante están viendo este tema.
mohai
Karoshi Fan
**
Mensajes: 80



« : 21 de Julio de 2009, 04:00:56 pm »

Me gustaría saber como hacer (a groso modo), para mover un sprite en pantalla de un punto a otro.
No me refiero a movimientos prefijados, si no a algo del tipo "muevete en línea recta del punto A al B" y ahora al punto C y ahora ...
He estado pensando en la teoría (la misma para dibujar una línea recta) y se me ha ocurrido algo así:

Primero se calcula la relación de aspecto (aspect ratio) del rectángulo que forman las coordenadas origen y destino (16:9, 4:3, etc). De esta manera sabemos la relación de pasos que dar en horizontal y en vertical (llamémoslo ANCHO y ALTO).

Se hacen 2 bucles descontadores para ANCHO y ALTO que, cuando ANCHO o ALTO llegue a cero, se varía la coordenada, horizontal o vertical. Se reinicia el contador que es cero y a seguir, hasta que llegue al destino.

Para calcular la relación de aspecto, se me ha ocurrido que si hayamos el mínimo común múltiplo (mcm) del ancho y el alto, luego dividimos el mcm por el ancho y el alto, sacamos la relacion de aspecto. Lo he probado con varios ejemplos y siempre sale. (quereis saber si teneis una tele 16:9 real?  Tongue).

El problema ahora es calcular el mcm en asm, ponerse a multiplicar y tal, además de que los bucles descontadores podrían comer mucho tiempo...

¿Hay alguna manera de hacerlo más fácil?

He buscado por el foro, pero no he encontrado nada.

P.D.: Entre las dudas que me surgen y que tengo el ASM más oxidado que la chapa del Titánic...
En línea
OKI09
Karoshi Maniac
****
Mensajes: 275



WWW Email
« Respuesta #1 : 21 de Julio de 2009, 09:19:06 pm »

Hace unos meses pregunte yo algo parecido, mira en este hilo.

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

Si tienes alguna duda, lo dices.
En línea

La derrota no es una opción y no hay excusas.
"Parasiempre"
mohai
Karoshi Fan
**
Mensajes: 80



« Respuesta #2 : 06 de Agosto de 2009, 12:24:50 pm »

Buenas,

ya tengo funcionando una rutinilla para calcular el desplazamiento de un objeto (válido para dibujar una línea)

Parto de la base de que cuando algo se mueve sobre 2 ejes, el desplazamiento mayor siempre es de 1 ren 1, mientras que el menor, es menor de 1. Así, asigno un valor de "paso" de 1 para el desplazamiento mayor en uno de los ejes. A partir del rectángulo que forman el punto inicial y el final es fácil saberlo.

Ahora el problema es pasarla a C/M (¿Algún voluntario?  Wink ). La rutina debería manejar decimales y no perder demasiada precisión.

Esta es la rutina:

Código:
1 'save"LINEAL  .BAS",a
5 CLS
10 'algoritmo para desplazamiento
20 'lineal de un sprite
30 '
40 '
50 'punto inicio
60 INPUT "Inicio X,Y";XA,YA
70 '
80 'punto destino
90 INPUT "Destino X,Y";XB,YB
110 '
120 'calculo alto y ancho
130 'manteniendo el signo positivo o negativo. No vale usar SGN
140 AL=YB-YA
150 AN=XB-XA
152 IF AL<0 THEN AL=AL-1 ELSE AL=AL+1
155 IF AN<0 THEN AN=AN-1 ELSE AN=AN+1
160 '
200 'calculo del aspecto tipo 1:0.n
210 IF ABS(AL)>ABS(AN) THEN IX=ABS(AN/AL):IY=1 ELSE IF ABS(AL)<ABS(AN) THEN IX=1:IY=ABS(AL/AN) ELSE IX=1:IY=1
220 '
230 'ajuste relaciones con signo
240 IX=IX*SGN(AN):IY=IY*SGN(AL)
500 PRINT
510 PRINT"Alto ";AL
520 PRINT"Ancho ";AN
530 PRINT
550 PRINT"Relacion de aspecto ";IX;":";IY
1000 PRINT
1005 PRINT "A continuacion se representara la linea. Primero se dibujara con el comando LINE del BASIC. Pulsa una tecla para que se dibuje punto a punto con los valores calculados."
1007 PRINT
1010 PRINT "Pulsa una tecla para continuar ";INPUT$(1)
1020 '
1030 COLOR 15,4,4
1040 SCREEN 5
1050 '
1060 LINE (XA,YA)-(XB,YB),15
1070 '
1080 PRINT INPUT$(1)
1090 '
1100 X=XA:Y=YA
1105 IF ABS(AN)>ABS(AL) THEN S=ABS(AN) ELSE S=ABS(AL) 'S toma el valor del eje mayor = pasos
1110 '
1115 PSET (X,Y),1
1120    X=X+IX
1130    Y=Y+IY
1140    'se decrementa el contador de pasos "1". si es 0, hemos acabado
1150    S=S-1
1160 IF S>0 THEN 1110
9999 BEEP
10000 PRINT INPUT$(1)

P.D.: Podéis modificar y usar la rutina como queráis.
En línea
pitpan
Karoshi Forum's Guru
*******
Mensajes: 1812


« Respuesta #3 : 06 de Agosto de 2009, 01:23:28 pm »

Buenas, buenas.

Como comprenderás, si tu rutina incorpora multiplicaciones y divisiones con decimales, además de ser lenta será bastante infernal pasarla a ensamblador. Siento no haberme metido antes en ello, pero probablemente lo que necesitas es comprender y usar el algoritmo de línea de Bresenham. Es, por así decirlo, el estándar para trazado y recorrido en videojuegos y ordenadores en general. La ventaja principal que tiene es que es muy poco costoso en términos de cálculo, ya que sólo emplea sumas, restas y desplazamientos. Además, seguro que puedes encontrar diversas implementaciones para ensamblador de Z80 ya preparadas por ahí...

Espero que te sea de alguna ayuda...
En línea
pitpan
Karoshi Forum's Guru
*******
Mensajes: 1812


« Respuesta #4 : 06 de Agosto de 2009, 01:25:23 pm »

Por cierto, que debo decir que la primera referencia a este algoritmo me la proporcionó Ramones, profesional donde los haya en el tema del desarrollo de video-juegos. Si no recuerdo mal, empleó esta técnica en el juego Majikazo.
En línea
mohai
Karoshi Fan
**
Mensajes: 80



« Respuesta #5 : 07 de Agosto de 2009, 05:10:39 pm »

Como comprenderás, si tu rutina incorpora multiplicaciones y divisiones con decimales, además de ser lenta será bastante infernal pasarla a ensamblador.
Si te fijas bien, la rutina solo hace una división. Divide el ancho y el alto (o a la inversa, dependidiendo de la dimensión mayor). Las mulitplicaciones son sólo para sacar los valores con signo y hacer más sencillo el programa. El bucle principal son simples sumas.

Siento no haberme metido antes en ello, pero probablemente lo que necesitas es comprender y usar el algoritmo de línea de Bresenham. Es, por así decirlo, el estándar para trazado y recorrido en videojuegos y ordenadores en general. La ventaja principal que tiene es que es muy poco costoso en términos de cálculo, ya que sólo emplea sumas, restas y desplazamientos. Además, seguro que puedes encontrar diversas implementaciones para ensamblador de Z80 ya preparadas por ahí...
Gracias!. Le echaré un vistazo.

salu2
En línea
mohai
Karoshi Fan
**
Mensajes: 80



« Respuesta #6 : 19 de Agosto de 2009, 09:15:25 am »

Os dejo la version 2, que no usa ni divisiones ni multiplicaciones. Seguramente se podrá hacer más sencilla. Ya os lo diré cuando me ponga a ASMizarla ...

Por cierto, experimentando con esta rutina, he descubierto varias curiosidades del BASIC, como que recorta las coordenadas que se salen de pantalla y distorsiona las líneas que apuntan fuera de ella, o que mis líneas no quedan igual que las hace el BASIC...

Por cierto, aún no he mirado el algoritmo de Bresenham (que ya me vale  Tongue ). Tal vez le eche un vistazo para ver una alternativa.

NOTAS: La rutina está hecha para hacer el movimiento de un sprite. Si se quiere representar una línea, basta quitar el REM de la línea 1127, quitar la 1168 y modificar la condición de la 1190.

Código:
5 CLS
7 DEFINT A-Z
10 'algoritmo para desplazamiento
20 'lineal de un sprite
30 'v 2 - orientado a ASM - 19/8/2009
40 '
50 'punto inicio
60 INPUT "Inicio X,Y";XA,YA
70 '
80 'punto destino
90 INPUT "Destino X,Y";XB,YB
110 '
120 'calculo alto y ancho
130 'y valores absolutos
140 AL=YB-YA
150 AN=XB-XA
160 '
162 BL=ABS(AL)
165 BN=ABS(AN)
170 IF BN>BL THEN S=BN ELSE S=BL 'S toma el valor del eje mayor = pasos
200 'incrementar o decrementar coordenadas?
210 IF AN<0 THEN IX=-1 ELSE IX=1
220 IF AL<0 THEN IY=-1 ELSE IY=1
500 PRINT
510 PRINT"Alto ";AL
520 PRINT"Ancho ";AN
530 PRINT
550 PRINT"Pasos (longitud de linea)";S
560 PRINT
570 PRINT"Incremento X,Y ";IX,IY
1000 PRINT
1005 PRINT "A continuacion se representara la linea. Primero se dibujara con el comando LINE del BASIC. Pulsa una tecla para que se dibuje punto a punto con los valores calculados."
1007 PRINT
1010 PRINT "Pulsa una tecla para continuar ";INPUT$(1)
1020 '
1030 COLOR 15,4,4
1040 SCREEN 5
1042 OPEN "grp:" AS 1
1050 '
1060 LINE (XA,YA)-(XB,YB),15
1070 '
1080 PRINT INPUT$(1)
1090 '
1100 X=XA:Y=YA
1110 PX=BN:PY=BL 'contadores de "pasos"
1120 'se resta la dimension menor de la mayor
1125 '
1127 REM PSET (X,Y),1
1130    IF PX>=PY THEN PX=PX-PY:X=X+IX:PY=BL
1140    IF PY>=PX THEN PY=PY-PX:Y=Y+IY:PX=BN
1168    PSET (X,Y),1
1170    'se decrementa el contador de pasos "1". si es 0, hemos acabado
1180    S=S-1
1185 REM PRINT INPUT$(1)
1190 IF S>0 THEN 1120
1999 PRINT INPUT$(1)
2000 PSET (XB,YB),7
9999 BEEP
10000 PRINT INPUT$(1)

Código:
En línea
kabish
Karoshi Maniac
****
Mensajes: 470


caspaflims@hotmail.com
« Respuesta #7 : 27 de Septiembre de 2009, 06:52:15 pm »

Sobre el Algoritmo de Bresenham, he encontrado un articulo donde lo explican en la revista Hnostar numero 25. He intentado escanearlo pero resulta que el escaner esta roto, asi que he echo unas cutrefotos con la camara y he transcrito el codigo de ejemplo.

Lo teneis zipeado aqui ..
http://kabish666.googlepages.com/bresenham_z80.zip

Espero que te sirva.

Un saludo.
En línea
mohai
Karoshi Fan
**
Mensajes: 80



« Respuesta #8 : 02 de Octubre de 2009, 12:00:19 am »

Gracias de nuevo.
Le echaré un vistazo si me atasco.

La verdad es que hace tiempo que tengo ASMizado el programa anterior, aunque no probado.
Tengo que ponerme con ganas y tiempo e ir sacando rutinillas, porque tengo el ASM más oxidado que los tornillos del Titanic.
En línea
Páginas: [1]
  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!