Suponiendo los siguientes datos que definen los sprites:
-sprite 0: x0, y0, a0 (ancho), b0 (alto)
-sprite 1: x1, y1, a1 (ancho), b1 (alto)
La explicación la dejo solo con la coordenada x, con la y es exactamente igual. La rutina lo que hace es mirar si la coordenada x0 del sprite 0 está dentro del rango x1-a0 a x1-a1, si está dentro de ese rango los sprites se tocan, en caso contrario no.
El rango x1-a0 a x1-a1 sería el rango límite juntando los dos sprites hasta que se rocen en coordenada x así que se mira si la x0 está en ese rango, en cuyo caso habría colisión. A ver si el siguiente esquema ayuda a entender la idea: Colisión:
x0>=(x1-a0) AND x0<=(x1+a1)
O visto de otro modo, no hay colisión si:
x0<(x1-a0) OR x0>(x1+a1)
Que es lo que mira la rutina en realidad, y normalmente será más rápido (y habitual) mirar si no colisionan que si lo hacen.
Código: Seleccionar todo
;sprite 1 -> IX
;ix+8: x1
;ix+9: y1
;ix+2: ancho sprite 1
;ix+3: alto sprite 1
;sprite 2 -> IY
;iy+8: x2
;iy+9: y2
;iy+2: ancho sprite 2
;iy+3: alto sprite 2
Ld a, (ix+8) ;A=xo
sub (iy+2) ;x0-a1
ld d,a
jp nc,s0012
xor a
s0012:
cp (iy+8) ;x1<x0-a1? está fuera
jp z, s0013 ;x1<A FUERA
jp nc, no_collision ;x1<A FUERA
s0013:
ld a,d
add (iy+2)
add (ix+2) ;xo+a0
dec a
cp (iy+8) ;x1>xo+a0? está fuera
jp c, no_collision ;x1>A+a0+a1 FUERA
Ld a, (ix+9) ;A=yo
sub (iy+3) ;y0-b1
cp (iy+9) ;y1<A? está fuera
jp nc, no_collision ;x1<A FUERA
add (iy+3)
add (ix+3) ;Y=y0+b0
dec a
cp (iy+9) ;y1>y0+b0? está fuera
jp c, no_collision
collision:
scf
ret
no_collision:
xor a
ret