Autor Tema: Colision de Sprites en Ensamblador  (Leído 8600 veces)

R. INTERNATIONAL

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 667
  • THE NEW IRON AGE HAS COME!!
    • Ver Perfil
Colision de Sprites en Ensamblador
« en: Febrero 28, 2012, 09:21:52 »
Tengo una duda a ver si alguien me la puede solucionar por aqui y alomejor le sirve a otra persona en el futuro, se refiere a la deteccion de una colision entre Sprites.
Supongamos que yo tengo el Sprite #0 que controlo con el Joy y tengo el Sprite #1 que purula por la pantalla, quiero hacer que el ordenador detecte su colision.
En las posiciones del vic está ésta:

$D01E  ; SPRITE TO SPRITE COLISION, POSICION 53278

Imagino que a éste registro le tendre que meter el acumulador con valor $03 (3 en decimal) que aplica a los Sprites #0 y #1,..pero

Como se utiliza esa posicion?
Le meto el 3 y ya detecta la colision?
Cuando esta detectada a continuacion puedo ya apagar el sprite que quiero y volver al menu principal?
Hay que hacer algo mas?
El Registro $DO1E le meto al principio de todo el meollo o cada vez que efectue un movimiento y lo chequee?

 En definitiva, una vez que esta detectada la colision lo que quiero es apargar el Sprite #0 y volver al menu principal que eso es facil:

LDA #$02   ; VALOR SPRITE 1
STA $D015  ; AL HIERRO Y APAGO EL 0
JMP MENU   ; VOLVER A MENU PRINCIPAL

  Un saludo.

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 13630
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Re:Colision de Sprites en Ensamblador
« Respuesta #1 en: Febrero 28, 2012, 16:45:44 »
No creo que te sirva de mucho porque no voy a decir nada de ensamblador, pero bueno, aqui va mi aporte:

Tienes que leer $D01E y si el valor devuelto es 0 entonces no hay ninguna colision entre los sprites.
Para saber que sprites se estan tocando tienes que ver si el bit correspondiente a tu sprite esta encendido, por ejemplo con un AND $01 y si el valor es distinto a cero hay colision.

Es mas o menos como lo resolví desde C, para ensamblador ya tendrás que esperar respuesta de los que saben!!
www.retroinvaders.com | www.commodoreplus.org  | josepzin.blogspot.com

R. INTERNATIONAL

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 667
  • THE NEW IRON AGE HAS COME!!
    • Ver Perfil
Re:Colision de Sprites en Ensamblador
« Respuesta #2 en: Febrero 28, 2012, 19:19:59 »
Gracias en cualquier caso, la verdad es que tiene que tener su cosa, no creo que sea tan facil como me he supuesto al principio, esperare respuestas.

A ver si alguien tiene algun listadito en el que se haga eso y asi ya lo ire destripando tranquilamente, te voy a mandar a tu correo Zanni una churufleta que tengo en Ensamblador para que veas como voy...

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 13630
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Re:Colision de Sprites en Ensamblador
« Respuesta #3 en: Febrero 29, 2012, 09:54:14 »
Ya he visto tu correo : ¡MOLA! ya te contestaré bien, que estoy entregando un trabajo y no tego tiempo ni para respirar!

Se me ocurre que para detectar las colisiones con el sprite 1 te puede servir esto:

Código: [Seleccionar]
LDA $D01E
AND $01
BNE hay_colision

BNE  <- bifurcar si el resultado no es 0
Para el sprite 2 sería AND $02 (creo) #00000010
www.retroinvaders.com | www.commodoreplus.org  | josepzin.blogspot.com

R. INTERNATIONAL

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 667
  • THE NEW IRON AGE HAS COME!!
    • Ver Perfil
Re:Colision de Sprites en Ensamblador
« Respuesta #4 en: Febrero 29, 2012, 13:16:56 »
Hace dos años se abrio un hilo relacionado con éste tema en la Pag.2, en él no se habla mucho pero remite a esta pagina:

http://codebase64.org/doku.php?id=base:simple_software_sprite_to_sprite_collision

Aqui creo que lo hace de otra forma, delimitando las zonas que ocupa el sprites y detectando cualquier coincidencia entre zonas, ese listado lo estudiare mas tranquilamente...

En C-64 Wiki, abajo de la pagina no dan mucha informacion pero si clarificante:

http://c64-wiki.com/index.php/Sprite

Vemos que abajo nos dice esto:
"Sprites involucrados en una colisión con otros sprites tendrán sus respectivos bits a "1" en la dirección 53278 / $ D01E - todos los sprites otros tendrán un "0" poco aquí.
"


Es decir, justo lo que decia al principio del tema, a la posicion $ D01E (53278) le meto el valor $03 (que aplica a los Sprites #0 y #1 y su bit ya queda a 1,..esto ya lo he probado asi a secas y no funciona...

Me faltaria meterle la Logica AND para comparar ambos bit, que se basa en esto:
1  1  ->  1   
1  0  ->  0
0  1  ->  0
0  0  ->  0
Es decir que al compararlos solo Le sale 1 si ambos esta a 1, en ese momento imagino que ya podria meterle una rutina que quiera (explosion) por ejemplo y volver al menu principal y volviendo a los parametros de inicio,...en el caso de que la comparacion me diera 0, volveria a la rutina que continua con la secuencia como si nada hubiera pasado

Todo esto es teorica, lo tengo que probar a ver si funciona o si me falta algo,.un borrador del listado seria éste, teniendo en cuenta que despues de la Etiqueta UPDATE vendrian las rutinas de Valores Iniciales y despues de la Etiqueta MAINLOOP la secuencia de movimientos del #0 por Joy y del #1 programada:

UPDATE                               ;VALORES INICIALES
                                           ;
                                           ;
MAINLOOP                          ;SECUENCIAS DE
                                           ;MOVIMIENTOS
                                           ;
                    LDA #03         ;BIT A 1 EN #0 Y #1
                    STA $D01E      ;AL HIERRO SPRITE TO SPRITE
                    AND $01         ;COMPARA 1
                    BNE UPDATE   ;SI NO ES 0 COLISION DETECTADA
                                           ;VUELVE A INICIO UPDATE
JMP MAINLOOP                   ;(SI ES 0) VUELVE A MAINLOOP
                                           ;Y SIGUE SU CURSO LA SECUENCIA
 
   Así,..todo esto es teorica, seguro que falta algo o me he equivocado en algo, o lo que sea,.tendre que probarlo, de todas formas no tengo prisa,..tengo todavia mucho que aprender.
   
« última modificación: Febrero 29, 2012, 13:26:02 por R. International »

Carlos

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 652
    • Ver Perfil
Re:Colision de Sprites en Ensamblador
« Respuesta #5 en: Febrero 29, 2012, 14:31:41 »
Hoy estoy liado pero mañana, si nadie lo ha hecho aún, te respondo.

R. INTERNATIONAL

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 667
  • THE NEW IRON AGE HAS COME!!
    • Ver Perfil
Re:Colision de Sprites en Ensamblador
« Respuesta #6 en: Febrero 29, 2012, 14:37:57 »
Gracias Carlos,..voy a buscar tu correo y te voy a mandar una Churufleta muy graciosa para que veas como voy!!!

R. INTERNATIONAL

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 667
  • THE NEW IRON AGE HAS COME!!
    • Ver Perfil
Re:Colision de Sprites en Ensamblador
« Respuesta #7 en: Febrero 29, 2012, 17:40:45 »
Por lo poco que estoy viendo ya me puedo olvidar del listado que he puesto ya que en foros como Lemon que hablan del tema, ya de entrada recomiendan que el detectar de colision es mejor hacerlo por Software y por zonas que por Hardware,..osea que me tendre que poner las pilas con el primer listado y enfocar mis energias por éste camino...

http://codebase64.org/doku.php?id=base:simple_software_sprite_to_sprite_collision

 En el fondo es totalmente logico ya que un Sprite (aunque no se utilize todo su area) tiene una cierta extension hacia X e Y, no se puede reducir el tema a un bit encendido o a un solo punto en las coordenadas.
« última modificación: Febrero 29, 2012, 17:43:55 por R. International »

pastbytes

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 556
  • SYS 0
    • Ver Perfil
Re:Colision de Sprites en Ensamblador
« Respuesta #8 en: Febrero 29, 2012, 21:51:04 »
Yo nunca probe este tema de la colision, pero si dice que se pone a 1 el bit de cada sprite involucrado en la colision, y en este caso seria 3, es decir los sprites 0 y 1, lo que hay que hacer para saber si esta condicion se da, es justamente un AND #$03 con el registro y luego comparar que ambos bits estan activados (o hacer XOR con el valor $03, que da 0 si estan ambos bits activados), si hacemos AND #$01 solo analizamos si el sprite 0 colisiona con cualquier otro. Y quiero creer que si el VIC tiene deteccion de colision por hard, y sabe que puntos del sprites son transparentes y cuales estan encendidos, la colision no detecta un solo punto del sprite sino toda la extension este ampliado o no, e ignorando los puntos no usados, pero como dije nunca experimente con esto.
« última modificación: Febrero 29, 2012, 21:54:53 por pastbytes »

Carlos

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 652
    • Ver Perfil
Re:Colision de Sprites en Ensamblador
« Respuesta #9 en: Marzo 01, 2012, 09:03:12 »
Voy a intentar explicarme de forma breve pero clara ya que es un tema que da para mucho:

- Sobre lo de usar detección de colisiones de sprites por hardware vs. software: La respuesta es depende, normalmente será mejor por software ya que nos va a permitir cosas que por hardware no es posible pero en el caso que tu planteas (un sprite que controlas con el joystick y otro que está en pantalla) la colisión por hardware es la opción más sencilla sin duda.

- Como hacer la detección por hardware: Creo que tienes un fallo de concepto, no se trata de escribir en el registro del VIC ($d01e) el valor de los sprites que quieres ver si colisionan o no, se trata unicamente de leer ese registro. El VIC ya se encarga de poner (sin que tu le digas nada) que sprites estan en colisión, cada bit en ese registro (son 8 ) nos indica si está a 1 que ese sprite está en colisión y si está a 0 que no lo está.

Ejemplo (supongamos que el registro 0 es una nave y el 1 una churufleta como dices tu :) :

     
Código: [Seleccionar]
lda $d01e    ; Leo en el acumulador el registro del VIC de colision sprite/sprite
lsr                ; Hago un desplazamiento a la derecha por lo que el bit 0 va a ir al flag de carry
bcc COLISION    ; En caso de que = 1 voy al codigo de colision
rts                ; No hay colision

COLISION:
     ; Aqui hago lo que sea en caso de colision

lo he escrito de memoria pero sería algo así, ten en cuenta que en cuanto leas ese registro ($d01e) se limpia, es decir, los valores se borran.

Hay una opción mas elegante para evitar tener que estar leyendo continuamente el registro de colisión para saber si hay una colisión o no y es hacer que el VIC te avise cuando hay una colisión (y después tu comprobarás que sprites son los que están en colisión) y es activando las interrupciones por colisión de sprites pero eso ya es otro tema y sería liar mucho las cosas ahora...

R. INTERNATIONAL

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 667
  • THE NEW IRON AGE HAS COME!!
    • Ver Perfil
Re:Colision de Sprites en Ensamblador
« Respuesta #10 en: Marzo 01, 2012, 09:52:34 »
Guai!!!, hoy lo pruebo, ayer estuve probando por la noche el listado que hice yo pero no funcionaba, hoy pruebo el tuyo, algunas preguntitas:
-¿Este listado que has puesto detecta cualquier punto de la zona del Sprite Pixelado?, ¿O todo el area? ¿o solo un punto coincidente en ambas coordenadas?
- Veo que me dices:
Ejemplo (supongamos que el registro 0 es una nave y el 1 una churufleta
Pero en el listado no aparecen los registros, con lo cual la deteccion es entre todos los Sprites, ¿Se puede hacer que detecte solo los que yo quiero, si utilizo mas?

  Un saludo, por cierto en tu perfil no sale tu correo, mandame uno a retrogamesystems(arr.obo)hotmail.com y te lo devuelvo con el Ejercicio para que lo veas, que me hace ilu!!

Carlos

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 652
    • Ver Perfil
Re:Colision de Sprites en Ensamblador
« Respuesta #11 en: Marzo 01, 2012, 10:18:51 »
Guai!!!, hoy lo pruebo, ayer estuve probando por la noche el listado que hice yo pero no funcionaba, hoy pruebo el tuyo, algunas preguntitas:

Cógelo con pinzas pero la idea es esa, una vez que hayas cargado el valor del registro $d01e en el acumulador la idea es comprobar que bits están a 1 de los que te interesan. Eso lo puedes hacer con desplazamientos y comprobando el carry flag, con un AND u OR lógico y comprobando el resultado final, etc...

-¿Este listado que has puesto detecta cualquier punto de la zona del Sprite Pixelado?, ¿O todo el area? ¿o solo un punto coincidente en ambas coordenadas?

La colision por hardware de sprite/sprite del VIC lo que detecta es que hay colision entre al menos un punto (pixel) que no sea transparente entre dos sprites, ni mas ni menos. No acabo de pillar mucho la pregunta.

- Veo que me dices:
Ejemplo (supongamos que el registro 0 es una nave y el 1 una churufleta
Pero en el listado no aparecen los registros, con lo cual la deteccion es entre todos los Sprites, ¿Se puede hacer que detecte solo los que yo quiero, si utilizo mas?

He supuesto que sólo estamos manejando 2 sprites y concretamente los sprites 0 y 1 que vendrán indicados en el registro $d01e por los bits 0 y 1 respectivamente por lo que no puede haber colisión con ningun otro sprite. Si quieres chequear otros sprites unicamente tienes que chequear los bits correspondientes del registro (hasta el bit 7 que se correspondería con el sprite 7) con las combinaciones que eso implica, de ahí que si tienes varios sprites en pantalla la detección software quizá no es la mejor opción pero si sólo son 2 no hay problema.

  Un saludo, por cierto en tu perfil no sale tu correo, mandame uno a retrogamesystems(arr.obo)hotmail.com y te lo devuelvo con el Ejercicio para que lo veas, que me hace ilu!!

Te mando un MP.

pastbytes

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 556
  • SYS 0
    • Ver Perfil
Re:Colision de Sprites en Ensamblador
« Respuesta #12 en: Marzo 01, 2012, 10:22:51 »
El codigo que Carlos te dio es para detectar que el sprite 0 colisiona con cualquier otro, si vas a usar varios sprites te conviene leer el registro, guardarlo e ir comparando por las combinaciones que esperes, por ejemplo sprite 0 con sprite 1 (00000011 = $03), sprite 0 con sprite 2 (00000101 = $05), etc., lo que tienes que hacer es leer el registro que guardaste y hacer XOR con el valor correspondiente, si quiero comparar si hubo colision entre 0 y 1, hago XOR con $03 (o %00000011 si queda mas claro), si da 0 la condicion es verdadera, luego puedo verificar si la colision fue del 0 con el 2, para eso tengo que leer el valor guardado del registro y hacer XOR con $05 (o %00000101), si da 0 la condicion es verdadera, y asi con todas las combinaciones que quieras.
Lo que dices de como se detecta la colision, es como deberia ser, que se toque cualquier punto del sprite con cualquiera del otro sin contar lo que no esta activado (color transparente), interpreto por lo que preguntas que supones que tal vez detecta la colision entre en cuadrado o rectangulo entero que ocuparia un sprite con el cuadrado o rectangulo entero del otro sprite, que yo sepa en todos los sistemas que tienen deteccion de colision de sprites te detecta los puntos activados nada mas, que esa es la gracia.

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 13630
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Re:Colision de Sprites en Ensamblador
« Respuesta #13 en: Marzo 01, 2012, 11:49:11 »
La colision por hardware es genial, detecta pixel al pixel e ignora los transparentes.
La colision tanto entre sprites como con el fondo, cuando se puede usar es muy práctica!
www.retroinvaders.com | www.commodoreplus.org  | josepzin.blogspot.com

pastbytes

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 556
  • SYS 0
    • Ver Perfil
Re:Colision de Sprites en Ensamblador
« Respuesta #14 en: Marzo 01, 2012, 12:19:19 »
Me olvide de decir que antes del XOR hay que hacer un AND con el mismo valor.
El registro dice quienes colisionaron, si solo te interesa saber si fue el sprite 0 con el 1, lees el registro, lo guardas para poder hacer otras comparaciones despues, y con ese valor hace un AND de los bits que te interesa saber si colisionaron, por ejemplo entre el 0 y el 1 haces un AND %00000011, esto elimina la informacion de los sprites 2 a 7 que no te interesan, luego ahi si haces el XOR a ese resultado tambien con el valor %00000011, si da 0 es que los sprites 0 y 1 colisionaron. El XOR es lo mismo que hacer una comparacion (en este caso que solo interesa la igualdad), tambien es valido si usas CMP, el XOR lo que hace es invertir los bits donde pongas un 1, si quieres saber si el acumulador contiene un 00000011, haces XOR con ese valor, lo cual invierte los bits 0 y 1, la unica forma de que el resultado de 0 es que el valor sea ese. Pero como dije lo mismo da si usas CMP y verificas si el resultado es 0, pero antes hay que hacer el AND para que te filtre solo los sprites que te interesa mirar.
Tambien puedes verificar si el bit del sprite que te interesa esta en 1 para saber si colisiono con algun otro, y despues verificar los otros 7 bits para saber con cual.
« última modificación: Marzo 01, 2012, 12:22:54 por pastbytes »