Karoshi MSX Community
05 de Julio de 2021, 11:55:44 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: Colisión píxel a píxel  (Leído 9913 veces)
0 Usuarios y 1 Visitante están viendo este tema.
Darth_Fistro
Karoshi Hero
*****
Mensajes: 507


Email
« : 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)  Grin 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  Tongue ¡Agradezco cualquier sugerencia!  Cheesy
En línea

MSX FOREVER (hasta que saquen un ZX81 con TMS, PSG y 64K de RAM)
Jon_Cortazar
Administrator
Karoshi Forum's God
********
Mensajes: 2777



WWW Email
« Respuesta #1 : 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?.
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.]
Darth_Fistro
Karoshi Hero
*****
Mensajes: 507


Email
« Respuesta #2 : 04 de Abril de 2007, 01:14:41 pm »

Cosas nada buenas, mi querido Jon  Wink

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.
En línea

MSX FOREVER (hasta que saquen un ZX81 con TMS, PSG y 64K de RAM)
jltursan
Karoshi Forum's Guru
*******
Mensajes: 1516


¿Que es lo que has aprendido hoy?


WWW Email
« Respuesta #3 : 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? Wink
En línea

Doom dee doom dee doom
Darth_Fistro
Karoshi Hero
*****
Mensajes: 507


Email
« Respuesta #4 : 04 de Abril de 2007, 02:51:04 pm »

Sí, es un simple point, JL  Wink ¿Un pop hl desaparecido? Hmmm... voy a ver ahora mismo  Cheesy
En línea

MSX FOREVER (hasta que saquen un ZX81 con TMS, PSG y 64K de RAM)
Darth_Fistro
Karoshi Hero
*****
Mensajes: 507


Email
« Respuesta #5 : 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é.
En línea

MSX FOREVER (hasta que saquen un ZX81 con TMS, PSG y 64K de RAM)
Darth_Fistro
Karoshi Hero
*****
Mensajes: 507


Email
« Respuesta #6 : 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?
En línea

MSX FOREVER (hasta que saquen un ZX81 con TMS, PSG y 64K de RAM)
WYZ
Visitante
« Respuesta #7 : 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]






« Última modificación: 08 de Abril de 2007, 11:36:27 am por WYZ » En línea
Darth_Fistro
Karoshi Hero
*****
Mensajes: 507


Email
« Respuesta #8 : 08 de Abril de 2007, 11:56:47 am »

¡Gracias!  Cheesy 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  Smiley Luego publico la rutina que uso. ¡Gracias!
En línea

MSX FOREVER (hasta que saquen un ZX81 con TMS, PSG y 64K de RAM)
WYZ
Visitante
« Respuesta #9 : 08 de Abril de 2007, 12:28:52 pm »

Usa esto 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]
....

« Última modificación: 08 de Abril de 2007, 12:31:39 pm por WYZ » En línea
Darth_Fistro
Karoshi Hero
*****
Mensajes: 507


Email
« Respuesta #10 : 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  Grin pero bueno, algo aprendo cada día  Smiley

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

¡Gracias!
« Última modificación: 08 de Abril de 2007, 01:10:55 pm por Darth_Fistro » En línea

MSX FOREVER (hasta que saquen un ZX81 con TMS, PSG y 64K de RAM)
Darth_Fistro
Karoshi Hero
*****
Mensajes: 507


Email
« Respuesta #11 : 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  Smiley
En línea

MSX FOREVER (hasta que saquen un ZX81 con TMS, PSG y 64K de RAM)
Darth_Fistro
Karoshi Hero
*****
Mensajes: 507


Email
« Respuesta #12 : 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í  Wink aunque sé que es mejor ahorrársela e incluirla directamente en el bucle.
En línea

MSX FOREVER (hasta que saquen un ZX81 con TMS, PSG y 64K de RAM)
WYZ
Visitante
« Respuesta #13 : 08 de Abril de 2007, 07:41:32 pm »

Pues esta muy bien! que quieres que te diga.  Wink. 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?  Roll Eyes
En línea
Darth_Fistro
Karoshi Hero
*****
Mensajes: 507


Email
« Respuesta #14 : 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  Wink

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  Undecided

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í.
En línea

MSX FOREVER (hasta que saquen un ZX81 con TMS, PSG y 64K de RAM)
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!