Commodore manía
Commodore 64 => Desarrollo => Mensaje iniciado por: Laddh en Abril 30, 2018, 14:02:23
-
Buenas gente, había leído sobre este asunto en los foros y hasta ahora no le había dado importancia porque no me he encontrado con este problema, pero en lo que estoy trabando ahora las colisiones por hard no funcionaban de manera precisa, la rutina que funcionaba hasta ahora, aquí se comía la mitad de las colisiones de una manera inaceptable. Dando un vistazo por Codebase64 empiezo a encontrar muchos apuntes a las colisiones por soft para solventarlo, comentando para mi sorpresa que cuando hay que controlar muchas cosas a la vez en pantalla, el registro de colisiones ya no es el adecuado para controlarlo.
Aquí aparece la idea de colisiones por soft, se trata de determinar las cuatro esquinas que conforman el sprite y comprobar si las coordenadas del interior de este rectángulo coincide con las coordenadas de otro sprite determinado del mismo modo.
Como me ha costado unos cuantos días pelearme con esto, aquí os paso mi primera aproximación a la solución del problema, creo que cualquiera que desarrolle se encontrará con esto en algún momento.
Saludos!
; 10 SYS (2064)
v=$d000 ;inicio registros sprite
*=$0801
BYTE $0E, $08, $0A, $00, $9E, $20, $28, $32, $30, $36, $34, $29, $00, $00, $00
*=$0810
jsr sprite
l jsr raster_wait
jsr JOY
jmp l
sprite lda #3 ;pon 2 sprites en pantalla
sta v+21
lda #0
sta v+39
lda #3
sta v+40
lda #192
sta 2040
lda #193
sta 2041
lda #100
sta v
lda #190
sta v+2
lda #147
sta v+1
sta v+3
rts
raster_wait ;espera línea raster
l1 LDA #$EA
CMP $D012
BNE l1
BIT $d011
BMI l1
rts
JOY LDA $DC00 ;LEEMOS JOY
AND #31 ;LA CUATRO DIRECCIONES ARRIBA ABAJO IZQ DER
CMP #30
BEQ ARR
CMP #29
BEQ ABJ
CMP #27
BEQ IZQ
CMP #23
BEQ DER
rts
arr dec $d001
jsr coordenadas
jsr comprueba_col
rts
abj inc $d001
jsr coordenadas
jsr comprueba_col
rts
izq dec $d000
jsr coordenadas
jsr comprueba_col
rts
der inc $d000
jsr coordenadas
jsr comprueba_col
rts
coordenadas ;actualiza coordenadas de los 2 sprites
lda v ;y crea 4 variables con las 4 esquinas
sta s1x1 ;de los sprites
clc ;s1x1 sprite 1 x1
adc #23 ;s1x2 sprite 1 x2
sta s1x2 ;etc....
lda v+1
sta s1y1
clc
adc #20
sta s1y2
lda v+2
sta s2x1
clc
adc #23
sta s2x2
lda v+3
sta s2y1
clc
adc #20
sta s2y2
rts
s1x1 byte 0
s1x2 byte 0
s1y1 byte 0
s1y2 byte 0
s2x1 byte 0
s2x2 byte 0
s2y1 byte 0
s2y2 byte 0
comprueba_col ;comprueba colisión en base a las coordenadas
lda s1x2 ;si se cumplen incrementa color borde
cmp s2x1
bcs comprueba_col1
rts
comprueba_col1
lda s1x1
cmp s2x2
bcc comprueba_col2
rts
comprueba_col2
lda s1y2
cmp s2y1
bcs comprueba_col3
rts
comprueba_col3
lda s1y1
cmp s2y2
bcc hit
rts
hit inc $d020
rts
*=12288
incbin"prueba.bin"
-
Qué curioso, ayer me estuve comiendo el tema de colisiones con sprites.
Una de las características que tiene es que cada vez que haces una lectura en la dirección de las colisiones, estas se resetean y por eso, si haces dos lecturas seguidas, la segunda da 0.
Lo que hice fué guardar el valor de la primera lectura en una "variable" y entonces trabajar con ella.
Como uso interrupciones para temas de movimiento, he usado las mismas interrupciones para que me detecte barrido o sprites dependiendo del código que se esté ejecutando.
Cuando entro en la rutina "activada" por raster ,donde muevo y muestro los sprites (varias veces del tirón por tema de velocidad/dificultad del nivel del juego usando un bucle), conmuto entonces a interrupciones por colision sprite/sprite y desvio a otro bloque si hay colision.
Una vez salgo de la rutina del raster, desactivo las interrupciones de sprites y activo la de raster ya que no va a moverse nada hasta que entre de nuevo.
Lo de coordenadas está bién por que puedes hacer que los sprites puedan "rozarse" sin que te maten XD, pero te obliga a usar sprites casi cuadrados.
Como en mi caso estaba usando un sprite arqueado, este método detectaria colisión sin tocarse en los extremos y se veria raro.
En teoria deberia poder hacerse con dos comprobaciones, como pintar un cubo en pantalla. Coordenadas orígen y coordenadas destino. Ahora me vas a tener pensando en ello todo el día... maldición ;D
-
Creo que seria algo así:
X=coordenada X de un sprite y el numero=sprites a comparar.
Se debe tener en cuenta el ancho y alto del sprite, en el caso de mi ejemplo, 8x8 pixéls.
8/2=4. Así que la resta que entregue valores de -4 al +4 indica colisión.
---------------------
X1=100 X2=98
Y1=100 Y2=100
X1-X2=xxx 100-98=+2 que indica colisión por eje X
Y1-Y2=xxx 100-100=0 Idem por eje Y
---------------------
X1=100 Y1=100
X2=104 Y2=106
X1-X2=xxx 100-104=-4 que indica colisión por eje X
Y1-Y2=xxx 100-104=-6 No hay colision por eje Y.
------------------------
Si usas un sprite de 8x16, 8/2 =-4 a +4 para ejes X y 16/2=-8 a +8 para ejes Y.
Cuando hay colision en ambos ejes, matas o explotas el sprite XD.
Si uno de llos falla, no pasa nada.
No la he probado, pero creo que es así. Prueba a ver si te funciona.
-
He hecho muchas pruebas desde que me encontré con el problema, y el bueno del registro de colisiones no daba la fiabilidad necesaria, tanto si lo miras desde la interrupción, como si lo miras inmediatamente después de cada movimiento o las dos a la vez, y en cambio la rutina por soft se muestra fiable 100*100.
Sí, obliga a que sean cuadrados pero si lo miras prácticamente todos los sprites lo son, se puede jugar con las coordenadas para que solo colisione con las centrales si el sprite tiene una forma rara.
En el ejemplo que adjunte controla los 24*21 de cada sprite como habrás visto pero es ajustable fácilmente.
Creo que a partir de ahora me decanto más por este sistema.
-
Te comprendo perfectamente.
Si solo chocan 2 sprites, no hay problema, pero con 3 ya es cuando hay que usar las coordenadas o te volverás loco.
Probe a desconectar los sprites no deseados y volver a comprobar colisiones y otras ideas que se me pasaron por la cabeza. Nada funcionó como me hubiera gustado.
Como estoy con un juego tipo Arkanoid, tocar el PAD con forma curvada es esencial, así que opté por evitar que otros sprites se tocasen entre ellos y a correr. Así no me ha fallado de momento, seguro que cuando lo ponga a prueba más a fondo la bola se enganchará en el pad cambiando de sentido sin fín o atravesará el pad... cruzare ese rio cuando llegue XD
-
Laddh, cuando dices que la interrupcion es imprecisa, es porque no detecta colisiones que han ocurrido, o por el problema de detectar qué sprites son los que han colisionado (cuando son más de dos)?
-
Hola Dashiad, sí, me refiero a que no detecta todas las colisiones, se saltaba muchas. La verdad es que no hay color, ahora que voy evolucionando la rutina por soft, es impecable.
-
Me parece raro que tenga problemas para detectar las colisiones pero bueno, tampoco soy un experto en el tema.
-
Precisamente por eso lo preguntaba...he estado buscando un poco sobre que las interrupciones no sean precisas, y no he encontrado referencias...Hay alguna que sepas, Laddh?
-
Uff, recuerdo haber leído artículos en Commodore World al respecto.
Creo que tiene que ver con el raster, que solo detecta las interrupciones cuando pasa o algo así.
Si los sprites van lentos seguro que pasa pero si el movimiento es rápido no, eso o que detecta en el segundo paso del raster despues de mover el sprite, algo había que lo hacía casi inútil en juegos rápidos.
Creo recordar que ya entonces abogaban por una rutina software.
La ventaja es que la interrupción hardware si que aplica la forma del Sprite mientras que una software sencilla es aplicar formas de caja. Hacer el análisis de si dos formas complejas se tocan o no es trabajoso.
Tiene sentido si pensamos como debe de funcionar, habrá un contador que va pasando por cada bit del bitmap o de la ROM de caracteres y pintando píxeles en la pantalla, mas o menos eso es el raster. Al mismo tiempo comprueba si en esa posición hay un sprite activado y entonces pinta el pixel del sprite en lugar del bitmap o caracer, pero si hay varios entonces pinta el de mayor prioridad y activa la interrupción. Algo pasa que la interrupción no se activa en ese momento, lo mismo se activa al terminar el cuadro para que no bombardee a interrupciones si al lado hay otros dos sprites colisionando. Si cuando termina el cuadro los sprites se han movido y se genera la interrupción y cuando vas al registro a ver cuáles están chicando, como ya no chocan no lo ves. Eso o que directamente no salta la interrupción si al acabar el cuadro los sprites ya no colisionan.
Me suena que la solución era poner una interrupción del raster Al final de la pantalla y solo mover sprites después de haber pintado toda la pantalla y haber atendido a todas las posibles colisiones. Eso además evita posibles parpadeos si da la casualidad de que mueves un sprite a mitad de pintarlo.
Eso también implica que si usas el raster para mostrar mas de ocho sprites a la vez en pantalla o sprites en los bordes ya no puedes usar las colisiones por hardware, o en todo caso solo podrás usar las de la última sección de la pantalla.
Espero no ser del todo inexacto y no haber 'desinformado' porque hace treinta y cinco años desde que leí el artículo y nunca lo apliqué.
-
Mm..yo lo que si que he leido, y a la vez, es logico, es que si un sprite (ej, una bala) se mueve a x pixeles por frame, y el enemigo se mueve a y pixeles por frame, en direccion contraria, si la bala pasa por una zona del enemigo que sea menos ancha de x+y pixeles, no va a haber colision...porque efectivamente, nunca la ha habido.
Como bien dices, la colision se detecta en tiempo de raster, por lo que o en un frame realmente se dibuja un sprite encima de otro, o no ha habido colision.
Pero si este es el problema, pasar a bounding boxes es una solucion parcial...el bounding box en ese caso es una forma aproximada de calcular un area de efecto.
Y si, por ganar precision, se reduce el bounding box para que coincida con la forma del sprite, el problema vuelve a ser el mismo...si los objetos se mueven demasiado rapido, se cruzan en vez de colisionar..Si es asi, la solucion seria basada en interpolar o aproximar las trayectorias.
-
Dashiad, el problema que yo me he encontrado no es que tenga que ver con la interrupción IRQ porque lo aplique sin interrupciones para probar, verificando el registro de colisiones a cada movimiento X,Y de los sprites y el resultado era el mismo, se comía muchas colisiones sin detectarlo, el contexto es los 8 sprites a la vez, naves, lasers, misiles..., como expliqué anteriormente me sorprendí porque esa misma rutina de colisiones había funcionado bien en proyectos anteriores.
Tal vez tenga que ver con lo que explica Scooter, el caso es que en búsquedas profundas por internet de este tema acabas leyendo comentarios de coders que efectivamente abogan por el método soft si quieres ser fiable al 100x100, despreciando el metodo hard por registro.
Mi moraleja por ahora es, primero prueba por registro de colisiones, es fácil de programar y si funciona adelante, que no, pues sistema soft, una vez lo entiendes tambien es fácil.
-
El registro de colisiones no lo puedes comprobar tras cada movimiento.Lo dispara el raster.El que cambies la posicion de un sprite no te genera una interrupcion.En el momento en el que el VIC intenta pintar los pixeles solapados por la colision, es cuando se genera.
-
Sí, ya, ya, no espero una colisión por comprobarlo pero manejo una nave, no se cuando va ha haber una colisión, y como podrás imaginar sincronizo cualquier movimiento en pantalla por raster.
Por cierto, un placer mantener una conversación técnica sobre commodore, da gusto comprobar que más gente entiende mi idioma. Una vez que el asm te atrapa ya no hay escape... ;)
-
Si mueves tres veces un Sprite entre raster y raster es un esfuerzo inútil porque solo se verá el último.
¿En serio se dispara la colisión en el mismo punto de la colisión o al terminar el cuadro?
Lo digo porque puedes tener dos sprites colisionando y un pixeles más allá otra colisión lo que llevaría a dos interrupcciones demasiado juntas en el tiempo.
Algo pasaba que efectivamente se perdían colisiones.
Me suena que la solución era mover los sprites solo en el tiempo del margen; poner una interrupción del raster en la línea 200 o 200 y poco de la pantalla, nada más terminar y entonces mover lo que sea.
Claro que eso llevaría a que si se refresca 50 veces por segundo limitas mucho la velocidad ya que en recorrer los 200 en vertical o los 320 en horizontal, tardas más de un segundo. Si saltas de 5 en 5 pixeles y la bala tiene 4 pixeles... Te lo puedes saltar. (Bueno, en realidad la suma de los anchos de los sprites...)
Pero claro, es que es tontería pintar más de un movimiento por barrido porque no se va a ver. Dependerá entonces de si es más fácil discriminar para solo pintar uno por barrido o pintar todos igual sin pensar, pero en ambos casos no funcionaría la colisión hardware.
Quizás una técnica mixta funcione bien. No sé.
-
Acabo de hacer unas pruebas con sprites y las colisiones.
Como comenté más arriba, desplazo varias veces los sprites durante un refresco de pantalla para así poder acelerar el ritmo del juego. Es un simple bucle contador.
Si la velocidad de movimiento (pixéles desplazados) no excede del tamaño de la bola (6 pixéles) , me reconoce todas las colisiones sin problemas.
Naturalmente, si a la vez estas desplazando el otro sprite con que colisiona (un pad o barrera de 2 pixeles de grueso por 22 de largo) , la suma de ambos consigue que se cuele entre esos 2 pixéles sin detectar colisión. Sí me detecta colisión con otro sprite que tengo justo debajo del pad haciendo de cuerpo.
Como desplazo la bola 1 pixél por cada 2 que se desplaza el pad, la velocidad máxima (pixeles desplazados) que puedo poner está entre 8 o 10. Contra más pixeles desplace la bola, mayores probabilidades de que aparezcan fallos en la detección.
Por las pruebas que he hecho, no detecta las colisiones hasta que no pasa el barrido por la pantalla, o eso parece.
Borrando la bandera de colisiones justo al entrar (con una colisión sprites activada) a la rutina de movimiento fuera de pantalla y leyendola de nuevo al finalizar , me da 0 colisiones (raster aún fuera de pantalla visible) a pesar de que ha habido colisión.
Una vez ya ha mostrado la pantalla, detecta la colisión.
-
Pues a lo mejor es un lío que te mueres pero...
Hacer una rutina de movimiento que mueva las variables de dónde se encuentra el Sprite pero no escriba los registros hasta que pase el raster para evitar posible flikeos, que salga repetido un Sprite por moverlo a una posición que está detrás del raster cuando ya había salido.
En los movimientos que no se realizan se hace una verificación por software aunque sea "de caja", o "de núcleo" mientras que en la que si que se pinta se hace caso a la interrupción.
Quizás la interrupción del raster pueda servir de reloj para controlar las velocidades de los movimientos.
No tengo claro que esté esquema sea más rápido o no. Lo que está claro es que complica el código pero puede que deje más tiempo libre ya que solo escribes en el VIC cuando avisa el raster y el resto del tiempo lo tienes par todo lo demás.
Para juegos lentos con la interrupción vale pero para los rápidos está claro que sí o sí hay que hacer algo por software.
-
Soy complicado ;D
Cada vez que me meto en un proyecto, aprovecho para probar cosas nuevas.
No me gusta usar bucles en el programa para hacer de freno, así que pensé en este sistema de control de velocidad por raster.
Está claro que me deja muchisimo tiempo de proceso fuera de las interrupciones para otras faenas como animar chars variables , puntuaciones y otros menesteres.
El sistema de detección por coordenadas es excelente, pero como ayuda a las colisiones multiples ya que si a cada ciclo compruebas las colisiones de 8 sprites a la vez con todas sus posibles combinaciones (creo que 28 posibles), debe de chupar una buena cantidad de recursos. Aunque está claro que nunca se van a utilizar todas, como mucho Bala contra malosos y protagonista contra todo XD.
Consultar las colisiones o hacer que activen una Interrupción hasta la rutina de comprobacion ayudaria a disminuir ese consumo de recursos consultando el valor devuelto, ayudaria a limitar la cantidad de comprobaciones entre coordenadas de sprites.
Llevo haciendo pruebas de colisiones entre sprites todo el día y nunca me han fallado si los desplazamientos de estos no se sobrepasan, impidiendo que los pixeles que los componen se toquen.
Dejo aqui un programilla que hice para trastear y tratar de sacar en claro como trabajan las interrupciones y los sprites.
Lo he comentado todo lo que he podido pero a estas horas ya no me queda combustible XD.
;CBM PRG STUDIO 3.12.0
;Programa para jugar con el raster y la detección de sprites.
;Main es el código normal que espera por comparación del raster a continuar.
;IRQ1 Se ejecuta por interrupción cuando el raster llega al valor establecido en RAS desde la subrutina IRQRASTER.
;Podeís jugar a variar los valores de ambos puntos raster para ver como afecta.
;Tened en cuenta que a cada lectura de colision de sprites, esta se pone a 0 automáticamente, así que
;si la rutina IRQ acaba de leer las colisiones, MAIN no leerá colisión alguna, pero lo muestro para tratar
;de hacer visible lo que ocurre a cada modificación que se haga en los valores de rasters.
;Al parecer , jugando con la zona a mostar sprites (RAS1=180 y RAS2=240) , la detección de colisiones ignora los sprites superiores y solo detecta los inferiores.
;Como podéis ver, activo o desactivo las colisiones por sprites mientras está dentro de IRQ1 ya que si estas están activas, al colisionar los sprites volverian
;a llamar a IRQ1 dando "tirones" en su ejecución.
;Espero que saquéis más cosas en claro que yo XD. Lo que si nunca ha fallado es la detección.
; 10 SYS4096
*=$0801
BYTE $0B, $08, $0A, $00, $9E, $34, $30, $39, $36, $00, $00, $00
*=$1000
start lda #00 ;Fondo y marco a negro
sta $d020
sta $d021
jsr putsprites ;Prepara y coloca los sprites.
jsr IRQRASTER ;Activa las interupciones.
MAIN lda $d012 ;RASTER
RAS1 cmp #100 ;Si no ha legado a la linea deseada, repite lectura.
bne MAIN
dec $d020 ;Cámbio de color del marco como pista de lo que está ocurriendo en pantalla.
inc SP2X ;Muevo sprite
lda SPSPCL ;Leer colisiones sprite sprite.
sta $0608 ;Muestra el valor de la colisión entre sprites.LInea superior.
inc $d020 ;Devuelve el color anterior al marco.
jmp MAIN
;-----------------------------------------------------------------------------
IRQ1 lda #04 ;Conectando IRQ por sprites. Evitas doble llamada a irq1
sta $d01a
inc $d020 ;Cambia color marco para mostar raster
asl $D019 ;Necesario para "reset raster"
inc SP0X ;Mover sprite.
lda SPSPCL ;Leer colision sprite sprite.
sta $0798 ;Muestra el valor de la colisión entre sprites. Linea inferior
lda #01 ;Conectando IRQ por RASTER
sta $d01a
dec $d020 ;Devuelve el color anterior al marco.
jmp $EA31 ;Salir de las interrupciones.
;SUBRUTINAS---SUBRUTINAS---SUBRUTINAS---SUBRUTINAS---SUBRUTINAS---
IRQRASTER
sei
lda #%00011011 ;27 original. 26 no flickea.Hibyte del raster pero
sta $D011 ;si no es 27 aparecen "pelos" en los bordes pantalla.
lda #<irq1 ;IRQ1=Raster
sta $0314
lda #>irq1
sta $0315
lda #%00000001 ;#127 en el ejemplo. Basta con activar el timer A #1
sta $DC0D ;Registro control de la cia
lda #01 ;Conecta IRQ por raster.
sta $D01A ;Registro mascara IRQ activada. IRQ ON. Col.Sprite ON
cli
RAS2 lda #240 ;linea activar barrido irq en la linea XX
sta $d012
rts
;-------------------------------------------------------------
PUTSPRITES ;Conectar sprites y colocarlos.
lda #15 ;8+4+2+1
sta SPENA ;Conectar sprite 0 , 1 , 2 , 3 y 4 Pad's' y bola
;Punteros de los sprites. 128
lda #128
sta POINSP0
sta POINSP1
sta POINSP2
sta POINSP3
lda #04
sta SP0COL
sta SP1COL
sta SP2COL
sta SP3COL
;Coordenadas X e Y sprites.
lda #140
sta SP0X
lda #231
sta SP0Y
lda #180
sta SP1X
lda #231
sta SP1Y
lda #140
sta SP2X
lda #150
sta SP2Y
lda #190
sta SP3X
lda #150
sta SP3Y
rts
;---------------------------------------------------------
*=$2000 ;SPRITE puntero 128
BYTE $3F,$FC,$00,$7F,$FE,$00,$FF,$FF,$00
BYTE $FF,$FF,$00,$FF,$FF,$00,$FF,$FF,$00
BYTE $7F,$FE,$00,$3F,$FC,$00,$00,$00,$00
BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00
BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00
BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00
BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00
BYTE $05
;***************************************************************************
;Constantes universales
; $D000-$D010 SPRITE HORIZONTAL AND VERTICAL POSITION REGISTERS
SP0X = $D000 ; SPRITE 0 X POSITION
SP0Y = $D001 ; SPRITE 0 Y POSITION
SP1X = $D002 ; SPRITE 1 X POSITION
SP1Y = $D003 ; SPRITE 1 Y POSITION
SP2X = $D004 ; SPRITE 2 X POSITION
SP2Y = $D005 ; SPRITE 2 Y POSITION
SP3X = $D006 ; SPRITE 3 X POSITION
SP3Y = $D007 ; SPRITE 3 Y POSITION
SP4X = $D008 ; SPRITE 4 X POSITION
SP4Y = $D009 ; SPRITE 4 Y POSITION
SP5X = $D00A ; SPRITE 5 X POSITION
SP5Y = $D00B ; SPRITE 5 Y POSITION
SP6X = $D00C ; SPRITE 6 X POSITION
SP6Y = $D00D ; SPRITE 6 Y POSITION
SP7X = $D00E ; SPRITE 7 X POSITION
SP7Y = $D00F ; SPRITE 7 Y POSITION
MSIGX = $D010 ; MSB'S OF SPRITES 0-7 HORIZONTAL POSITIONS
; POINTER SPRITES
POINSP0 = $07F8 ; POINTER 2040 SPRITE O
POINSP1 = $07F9 ; POINTER 2041 SPRITE 1
POINSP2 = $07FA ; POINTER 2042 SPRITE 2
POINSP3 = $07FB ; POINTER 2043 SPRITE 3
POINSP4 = $07FC ; POINTER 2044 SPRITE 4
POINSP5 = $07FD ; POINTER 2045 SPRITE 5
POINSP6 = $07FE ; POINTER 2046 SPRITE 6
POINSP7 = $07FF ; POINTER 2047 SPRITE 7
; $D011-$D012 SCROLL & RASTER
SCROLY = $D011 ; VERTICAL FINE SCROLLING AND CONTROL REGISTER
RASTER = $D012 ; READ CURRENT RASTER SCAN LINE/WRITE LINE TO COMPARE
; FOR RASTER IRQ
SPENA = $D015 ; SPRITE ENABLE REGISTER
SCROLX = $D016 ; HORIZONTAL FINE SCROLLING AND CONTROL REGISTER
YXPAND = $D017 ; SPRITE VERTICAL EXPANSION REGISTER
VMCSB = $D018 ; VIC-II CHIP MEMORY CONTROL REGISTER
VICIRQ = $D019 ; VIC INTERRUPT FLAG REGISTER
IRQMSK = $D01A ; IRQ MASK REGISTER
SPBGPR = $D01B ; SPRITE TO FOREGROUND DISPLAY PRIORITY REGISTER
SPMC = $D01C ; SPRITE MULTICOLOR REGISTERS
XXPAND = $D01D ; SPRITE HORIZONTAL EXPANSION REGISTER
; $D01E-$D01F SPRITE COLLISION DETECTION REGISTERS
SPSPCL = $D01E ; SPRITE TO SPRITE COLLISION REGISTER
SPBGCL = $D01F ; SPRITE TO FOREGROUND COLLISION REGISTER
; $D020-$D026 VIC-II COLOR REGISTER
EXTCOL = $D020 ; BORDER COLOR REGISTER
BGCOL0 = $D021 ; BACKGROUND COLOR 0
SPMC0 = $D025 ; SPRITE MULTICOLOR 0
SPMC1 = $D026 ; SPRITE MULTICOLOR 1
; $D027-$D02E SPRITE COLOR REGISTERS
SP0COL = $D027 ; SPRITE 0 COLOR
SP1COL = $D028 ; SPRITE 1 COLOR
SP2COL = $D029 ; SPRITE 2 COLOR
SP3COL = $D02A ; SPRITE 3 COLOR
SP4COL = $D02B ; SPRITE 4 COLOR
SP5COL = $D02C ; SPRITE 5 COLOR
SP6COL = $D02D ; SPRITE 6 COLOR
SP7COL = $D02E ; SPRITE 7 COLOR
; $D02F-$D03F NOT CONNECTED
; $D040-$D3FF VIC-II REGISTER IMAGES
; $D419-$D41A GAME PADDLE INPUTS
; $D41D-$D41F NOT CONNECTED
; $D420-$D7FF SID REGISTER IMAGES
; $D800-$DBFF COLOR RAM
COLRAM = $D800
; $DC00-$DC0F CIA #1
CIAPRA = $DC00 ; DATA PORT REGISTER A joy2
CIAPRB = $DC01 ; DATA PORT REGISTER B joy1
CIDDRA = $DC02 ; DATA DIRECTION REGISTER A
CIDDRB = $DC03 ; DATA DIRECTION REGISTER B
CIASDR = $DC0C ; SERIAL DATA PORT
CIAICR = $DC0D ; INTERRUPT CONTROL REGISTER
CIACRA = $DC0E ; CONTROL REGISTER A
CIACRB = $DC0F ; CONTROL REGISTER B
; $DC10-$DCFF CIA #1 REGISTER IMAGES
; $DD00-$DD0F CIA #2
; $DD10-$DDFF CIA #2 REGISTER IMAGES
LECOL = $0286 ; LETTER COLOR
GETIN = $FFE4
-
Aclarar que lo de apagar y desconectar las IRQ de colisiones no está completo.
Las IRQ de raster las envio a una rutina de movimiento y las de sprites a la rutina de comprobar colision.
Se puede hacer comprobando los bites de $D019, pero me gusta experimentar XD
-
Muy bueno Maniako!
-
Hay que tener en cuenta que en un juego como el que propone Maniako, tipo Arkanoid, si se hace por bounding box, la caja donde se metiera la bola deberia ser tan pequeña como la bola. Lo mismo para el pad. Si se utilizara una caja demasiado grande para cualquiera de los dos, quedaría muy inexacto.
Y, si es así, y simplemente se suman pixeles de movimiento, y se calculan colisiones, el problema es el mismo: la bola puede "saltarse" el pad.Y daría lo mismo que se haga por bounding boxes o por hardware, ya que las bounding boxes son pequeñas.
Por fuerza hay que interpolar la posición de la bola a la altura en la que se encuentra el pad, para ver si colisionaria o no.
En general, una cosa es la trayectoria que siguen los objetos, y otra es lo que se pinta en pantalla.Si cada punto de la trayectoria se va a pintar (cada uno de los pixeles), las interrupciones no deberian fallar nunca (otra cosa es que las bounding boxes deberian seguir usandose para saber qué sprites han colisionado entre si, si son más de dos).