Karoshi MSX Community

Desarrollo MSX => Desarrollo (Español/Spanish) => Mensaje iniciado por: Darth_Fistro en 04 de Abril de 2007, 10:52:12 am



Título: Colisión píxel a píxel
Publicado por: Darth_Fistro en 04 de Abril de 2007, 10:52:12 am
Bueno, estaba creando como siempre nuevos estándares de calidad en cuanto a desarrollo de juegos para el MSX (por lo bajo, claro)  ;D cuando me he topado con el siguiente problema.

Estoy haciendo una rutina que detecte si un punto en concreto de la pantalla está a 1 o 0, sobre la tabla de patrones. Así intento detectar colisiones de un sprite contra el fondo. He intentado varios enfoques pero la última que hice no funcionaba. La lógica que utilizo es la siguiente:

-cojo las posiciones x e y del sprite y redondeo con and 248, multiplico y*32 y le añado x.

-ahora para hallar cuál es el byte concreto, sumo la coord.y and 7

-se supone que debo tener en el registro hl la dirección del byte de la tabla de patrones que contiene el punto que me interesa comprobar.

-ahora quiero llevarme ese punto a la posición 7 dentro del byte. Para eso hallo coord.x and 7, y roto el byte a la izquierda ese nº de veces.

-debo tener en el bit nº7 del byte apuntado por el registro hl el punto de la pantalla a comprobar. Lo hago con la instrucción bit.

Pues nada, al menos quiero saber si ese procedimiento es correcto, igual es que las rutinas las hago mal, pero si el procedimiento no es eso no tengo nada que hacer  :P ¡Agradezco cualquier sugerencia!  :D


Título: Re: Colisión píxel a píxel
Publicado por: Jon_Cortazar en 04 de Abril de 2007, 12:21:47 pm
La madre del cordero!. Una colisión al pixel!... pues nunca las he hecho, las colisiones sprites+escenario siempre las he hecho a nivel de tiles (incluso en Malaika, aunque restando el hoffset del scroll)... ¿que estás perpetrando, maldito?.


Título: Re: Colisión píxel a píxel
Publicado por: Darth_Fistro en 04 de Abril de 2007, 01:14:41 pm
Cosas nada buenas, mi querido Jon  ;)

Tan sólo quiero identificar un bit determinado en la pantalla, creo que la colisión es básicamente eso, es decir, no me interesa comprobar un sprite entero contra escenario ni nada de eso, simplemente saber por ejemplo si estoy en la coordenada 150,100, el bit (que no sólo el byte) que estoy pisando.


Título: Re: Colisión píxel a píxel
Publicado por: jltursan en 04 de Abril de 2007, 02:08:17 pm
A ver, que me lío. ¿Tú lo que quieres es una rutina de "point", simplemente para ver si un punto dado está iluminado?, ¿o más bien es para buscar colisiones entre objetos que se muevan?. De todas formas si es la rutina que yo pienso, ¿le has echado un ojo a un "POP HL" desaparecido? ;)


Título: Re: Colisión píxel a píxel
Publicado por: Darth_Fistro en 04 de Abril de 2007, 02:51:04 pm
Sí, es un simple point, JL  ;) ¿Un pop hl desaparecido? Hmmm... voy a ver ahora mismo  :D


Título: Re: Colisión píxel a píxel
Publicado por: Darth_Fistro en 04 de Abril de 2007, 02:59:09 pm
Igual te refieres a la rutina ROTA_IZQUIERDA, pero tiene un push y un pop, a lo mejor cometí un error al copiar/pegar en el mensaje que te envié.


Título: Re: Colisión píxel a píxel
Publicado por: Darth_Fistro en 08 de Abril de 2007, 10:41:41 am
¿Alguna ideílla? ¿Y si miro la rutina POINT del basic? ¿Sabe alguien dónde empieza?


Título: Re: Colisión píxel a píxel
Publicado por: WYZ en 08 de Abril de 2007, 11:26:59 am
Esta es la rutina que uso normalmente, si quieres pega también la tuya aquí y podremos sacar una buena optimizaron para los snippets del foro:


Citar
-cojo las posiciones x e y del sprite y redondeo con and 248, multiplico y*32 y le añado x.


Código:
;YX TO TILES SIN OFFSET
;IN [HL]: [H]=X;[L]=Y => [0,$2FF]
;OUT [HL]: POS TILE SIN OFFSET

YX2TILES: RRC H ;X\8
RRC H
RRC H
LD A,L ;(Y\8)*20
LD L,H
AND 11111000B
LD E,A
LD H,0
LD D,0
ADD HL,DE
ADD HL,DE
ADD HL,DE
ADD HL,DE
RET

Ahora sumas la coordenada Y como dices y vpeekeas en esa dirección rotando el resto X. Si tuvieras la rutina en RAM podrías parchear el opcode BIT para que, en vez de rotar X veces, obtuvieras el BIT directamente:

Código:

solo en RAM:

                                   ; opcode

        BIT 0,A                 ; CB 47
        BIT 1,A                 ; CB 4F
        BIT 2,A                 ; CB 57
        BIT 3,A                 ; CB 5F
        BIT 4,A                 ; CB 67
        BIT 5,A                 ; CB 6F
        BIT 6,A                 ; CB 77
        BIT 7,A                 ; CB 7F

Para el reg. A : ($47+X*8)

$48 para B
$49 para C...D,E,H,L y [HL]








Título: Re: Colisión píxel a píxel
Publicado por: Darth_Fistro en 08 de Abril de 2007, 11:56:47 am
¡Gracias!  :D No entiendo bien la segunda parte, luego lo miro que me tengo que marchar. Dime por favor con qué códigos se abren las cajas de texto para insertar código, y que quede más bonito todo  :) Luego publico la rutina que uso. ¡Gracias!


Título: Re: Colisión píxel a píxel
Publicado por: WYZ en 08 de Abril de 2007, 12:28:52 pm
Usa esto (http://karoshi.msxgamesbox.com/Themes/babylon/images/bbc/quote.gif) para insertar texto con formato codigo

Código:
        ; EN VEZ DE ROTAR USA ESTO SI TU PROGRAMA ESTA EN RAM
        ; IN: [A]
       
push af
RLCA ;[A]X8
RLCA
RLCA
ADD $47
LD [PARCHE+1],A
pop af
PARCHE: BIT X,A ;Y AQUI TENDRAS EN BIT QUE INDICA [A]
....



Título: Re: Colisión píxel a píxel
Publicado por: Darth_Fistro en 08 de Abril de 2007, 01:04:14 pm
Gracias. Sigo sin saber exactamente que es PARCHE+1 y qué hace exactamente. Aquí te explico mi código:

La posición Y está en COORD_Y y la x en COORD_X. La pantalla se guarda en un buffer llamado PANT_BUFFER y apuntado por HL.

Citar
   ld   a,[COORD_X] ;redondeo la coord_x
   and    248
   ld   d,0
   ld   e,a

   ld   h,0
   ld   a,[COORD_Y] ;redondeo la coord_y y multiplico por 32
   and   248
   ld   l,a
   ld   c,32
   call   mult

   add   hl,de

La rutina "mult" que multiplica HL por un número dado en el registro C es:

Citar
;------------------------------------------
;Multiplica un número HL=número C= *n
;------------------------------------------
mult:
   ld   a,c
   or   a
   jp   z,@@cero
   push   de
   dec   c
   ld   b,c
   push   hl
   pop   de
@@buc1:
   add   hl,de
   djnz   @@buc1
   pop   de
   ret
@@cero:
   ld   hl,0
   ret

Bueno, ahora supuestamente estará en HL un número comprendido entre 0 y 6144 (la tabla de patrones) donde está el byte buscado. Aún tengo que sumar Y and 7 a HL para que HL apunte al byte específico:

Citar
   ld   a,[COORD_Y]
   and   7

   ld   d,0
   ld   e,a
   add   hl,de

Ahora sí HL debe apuntar al byte de la pantalla que contiene el punto a detectar.
Queda rotar ese byte a la izquierda tantas veces como X and 7.

Citar
   ld   a,[COORD_X]
   and   7
   or   a
   jp   z,@@sigue ;si es cero salto el paso de rotar

   ld   b,a
@@buc:
   push   bc   
   call   ROTA_IZQUIERDA
   pop   bc
   djnz   @@bu2

La rutina de rotación es:

Citar
ROTA_IZQUIERDA:
;---------------------------
;HL=dir.byte a rotar
;---------------------------

@@rota:
    sla [hl]
ret

Por último, cargo en A el valor del byte apuntado por HL y comparo el 7ºbit:

Citar
   ld   a,[hl]
   bit   7,a
   jp   nz, COLISION_AL_CANTO

Como ves, mi ensamblador es como para escribir la segunda parte del libro de Rodney Zacks  ;D pero bueno, algo aprendo cada día  :)

Tengo que ponerme a ver instrucciones como RRCA y todo eso, y aprender mejor a manipular nibbles y todo eso... pero poco a poco  ;)

¡Gracias!


Título: Re: Colisión píxel a píxel
Publicado por: Darth_Fistro en 08 de Abril de 2007, 01:05:21 pm
Por favor, sé cruel con las críticas del código, así es como se aprende  :)


Título: Re: Colisión píxel a píxel
Publicado por: Darth_Fistro en 08 de Abril de 2007, 01:12:37 pm
ROTA_IZQUIERDA es innecesaria tenerla como rutina separada, pero como formaba parte de otra rutina que fuí modificando, se me quedó así  ;) aunque sé que es mejor ahorrársela e incluirla directamente en el bucle.


Título: Re: Colisión píxel a píxel
Publicado por: WYZ en 08 de Abril de 2007, 07:41:32 pm
Pues esta muy bien! que quieres que te diga.  ;). Lo único es que no está optimizada. Siempre se pueden hacer las cosas con menos "material" pero eso se aprende, no te preocupes. Por ejemplo. una multiplicación por $20=32=2^5 es mas fácil hacerla rotando bits y acarreando que haciendo un bucle.

Tiene toda la pinta de un arkanoid o un lazer bikes, me equivoco?  ::)


Título: Re: Colisión píxel a píxel
Publicado por: Darth_Fistro en 08 de Abril de 2007, 09:06:39 pm
Gracias, aún queda escudriñar y optimizar, pero eso con todos los programas, están hechos un asquito  ;)

Si le has echado un vistazo al método, ¿cómo lo ves? ¿es correcto? Porque el caso es que la rutina no me funciona, detecta "colisiones" unas veces sí y otras no. Y creo que el sistema es correcto  :-\

El objetivo es para un juego filmation, como el Head over Heels. Todo me va bien pero quiero que en todo el escenario haya detección píxel a píxel y no a base de caracteres, porque los escenarios tienen inclinación de 30º y con una detección a base de caracteres se notan mucho los "cubiletes" cuando el personaje choca con algo.

No sé qué método usarían los programadores de estos juegos, pero supongo que necesitaré una pantalla buffer extra conteniendo sólo las colisiones. Vamos, "imprimir" la forma de los objetos que son obstáculos en una pantalla extra y comprobar las colisiones del personaje allí.


Título: Re: Colisión píxel a píxel
Publicado por: Jon_Cortazar en 08 de Abril de 2007, 09:17:34 pm
El objetivo es para un juego filmation, como el Head over Heels. Todo me va bien pero quiero que en todo el escenario haya detección píxel a píxel y no a base de caracteres, porque los escenarios tienen inclinación de 30º y con una detección a base de caracteres se notan mucho los "cubiletes" cuando el personaje choca con algo.

A ver, que así la cosa cambia...  ;)

¡Pues no compruebes las colisiones con la pantalla!  :D

¡Lo que tienes que hace es tener en memoria el mapa de la pantalla activa, pero en 2D, e ir haciendo las comprobaciones sobre ella, en lugar de sobre la representación gráfica en isométrica!. De esta forma compruebas simplemente leyendo la casilla correspondiente, con el correspondiente ahorro de memoria. Y si el problema es que tienes varios niveles de alturas, pues te guardas en memoria una matriz de 3 dimensiones con los datos de las tiles dentro de ese espacio y punto.


Título: Re: Colisión píxel a píxel
Publicado por: Darth_Fistro en 08 de Abril de 2007, 10:25:54 pm
Joder, ¡eres el rey del brainstorming!  :o ¡Ni se me había ocurrido!
¿Puedo contratarte como asesor técnico?  :D


Título: Re: Colisión píxel a píxel
Publicado por: Darth_Fistro en 08 de Abril de 2007, 10:27:27 pm
Entonces se reduce a pasar la pantalla a un buffer donde se representa en 2D, y realizar allí las comprobaciones como si de choque con caracteres se tratase. ¡Ingenioso al máximo!  :-*
No hay alturas, así que no problem. ¡Gracias!


Título: Re: Colisión píxel a píxel
Publicado por: Darth_Fistro en 08 de Abril de 2007, 10:29:06 pm
De todas formas, quiero resolver el problema de las colisiones porque me sirve para otro juego  ;)


Título: Re: Colisión píxel a píxel
Publicado por: Jon_Cortazar en 08 de Abril de 2007, 11:38:18 pm
Entonces se reduce a pasar la pantalla a un buffer donde se representa en 2D, y realizar allí las comprobaciones como si de choque con caracteres se tratase. ¡Ingenioso al máximo!  :-* No hay alturas, así que no problem. ¡Gracias!

Exacto, esa es la idea. De hecho, es como suele hacerse para que la cosa sea más fácil. De cualquier forma Juanma, me estás dando un miedo que no te puedes ni imaginar ;D, ¿para cuando empiezas a desvelar cosillas, pirata? :-*. De cualquier forma, ¡que bueno es tenerte de vuelta!  :D :D


Título: Re: Colisión píxel a píxel
Publicado por: Darth_Fistro en 09 de Abril de 2007, 09:06:38 am
Jejejeje, yo sí que me alegro de estar con vosotros  :D He estado diseñando sobre papel cuántos bytes gastaría por pantalla y es factible. Gracias, Jon, por la idea, porque has hecho que el proyecto se haga realidad, en serio. Es que me había quedado atascado en ese punto y ya no sabía cómo meterle mano. Plantearé todo el juego como si de un juego de laberintos se tratase, sobre un buffer en 2D (colisiones con los malos, obstáculos, etc) y sólo usaré el buffer en isométrico para volcar en la pantalla. ¡Es genial ese enfoque! Me ha devuelto la ilusión, jejeje.

Bueno, sobre los proyectos te diré que me lo estoy tomando con calma, en el sentido de que no le pongo fecha tope a ninguno, para no agobiarme. Y básicamente no hago juegos (me explico). Intento hacer rutinas nuevas que siempre me han llamado la atención y una vez hechas veo si es posible sacar algo de ahí. Tengo proyectos con scoll píxel a píxel, en parallax, laberínticos, filmation 1 y 2, jejeje. Pero he de centrarme en terminar lo que tengo ahora atrasado.

Eso sí, contad que el primer juego que se apuntará a la dev será el Goonies:The movie ;) (mapeando ya la tercera fase, jejejee...)


Título: Re: Colisión píxel a píxel
Publicado por: jltursan en 09 de Abril de 2007, 09:13:39 am
Citar
Tengo proyectos con scoll píxel a píxel, en parallax, laberínticos, filmation 1 y 2

¡Caray!, que se dice pronto... :)


Título: Re: Colisión píxel a píxel
Publicado por: Dioniso en 09 de Abril de 2007, 09:15:51 am
Pues por si te sirve de algo ... puedes ganar algo de velocidad si en la matriz que tengas en RAM para comprobaciones redefines, por ejemplo, los caracteres que sabes que no van a provocar colisión (diferentes tiles del suelo, por ejemplo) al final del banco (de 256 caracteres); imagínate que utilizas los caracteres desde 230 en adelante sólo para el suelo (no paredes) que no va a provocar colisión. De forma que antes de meterte en todo el pastelón de comprobar la detección de píxel lees en RAM si el caracter es igual o mayor a 230 ... y en caso afirmativo pasas de todo y a otra cosa, mariposa  ;D

Claro, que si los enemigos también son caracteres y se van a mover por toda la pantalla ...  :-\


Título: Re: Colisión píxel a píxel
Publicado por: Darth_Fistro en 09 de Abril de 2007, 09:29:17 am
Muchas gracias, Dioniso, ya tenía pensado hacerlo así  :) De todas formas, aunque no la use para ese juego, quiero una rutina de colisión píxel a píxel que me servirá para otro.

WYZ, I need you!  :-* ;D


Título: Re: Colisión píxel a píxel
Publicado por: Darth_Fistro en 10 de Abril de 2007, 12:20:37 pm
Bueno,pues implementado el sistema "Joniano"  ;) y la cosa va como la seda. He hecho dos versiones: un "minifilmation" usando dos tercios de la pantalla con muñecos de 16x24, todo en plan pequeñito, y uno más corriente con muñecos de 24x32 (como el Batman) a pantalla completa. Creo que seguiré con los dos enfoques (cada uno tiene su pequeño intríngulis con respecto a la pantalla, ya os contaré) así que perdonadme si ven la luz dos juegos con motores cuasi-iguales, jejejeje  :D


Título: Re: Colisión píxel a píxel
Publicado por: MsxKun en 11 de Abril de 2007, 12:38:21 pm
Bueno,pues implementado el sistema "Joniano"  ;) y la cosa va como la seda. He hecho dos versiones: un "minifilmation" usando dos tercios de la pantalla con muñecos de 16x24, todo en plan pequeñito, y uno más corriente con muñecos de 24x32 (como el Batman) a pantalla completa. Creo que seguiré con los dos enfoques (cada uno tiene su pequeño intríngulis con respecto a la pantalla, ya os contaré) así que perdonadme si ven la luz dos juegos con motores cuasi-iguales, jejejeje  :D

Exacto! Te perdonamos si salen dos juegos!!! Si no salen no! :D
Por cierto, al minifilmation ese podriamos llamarlo tecnica Fistration :)


Título: Re: Colisión píxel a píxel
Publicado por: Darth_Fistro en 11 de Abril de 2007, 01:10:12 pm
Jajaja  :D Seguro que uso una técnica con personalidad propia: más lenta, más derroche de memoria y lo más enrevesado posible. Así que sí, creo que sería un buen nombre  ;)